Commit e33a336ed93362a12658611a7b9660b4dba8e5e7
Merge remote-tracking branch 'origin/master' into feature/bulk-import/device-credentials
# Conflicts: # application/src/main/java/org/thingsboard/server/controller/DeviceController.java # application/src/main/java/org/thingsboard/server/controller/EdgeController.java # common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java # ui-ngx/src/app/core/http/device.service.ts
Showing
100 changed files
with
1270 additions
and
830 deletions
Too many changes to show.
To preserve performance only 100 of 261 files are displayed.
@@ -66,6 +66,10 @@ | @@ -66,6 +66,10 @@ | ||
66 | <artifactId>rule-engine-api</artifactId> | 66 | <artifactId>rule-engine-api</artifactId> |
67 | </dependency> | 67 | </dependency> |
68 | <dependency> | 68 | <dependency> |
69 | + <groupId>org.thingsboard.common</groupId> | ||
70 | + <artifactId>cluster-api</artifactId> | ||
71 | + </dependency> | ||
72 | + <dependency> | ||
69 | <groupId>org.thingsboard.rule-engine</groupId> | 73 | <groupId>org.thingsboard.rule-engine</groupId> |
70 | <artifactId>rule-engine-components</artifactId> | 74 | <artifactId>rule-engine-components</artifactId> |
71 | </dependency> | 75 | </dependency> |
@@ -290,6 +294,11 @@ | @@ -290,6 +294,11 @@ | ||
290 | <scope>test</scope> | 294 | <scope>test</scope> |
291 | </dependency> | 295 | </dependency> |
292 | <dependency> | 296 | <dependency> |
297 | + <groupId>org.awaitility</groupId> | ||
298 | + <artifactId>awaitility</artifactId> | ||
299 | + <scope>test</scope> | ||
300 | + </dependency> | ||
301 | + <dependency> | ||
293 | <groupId>org.mockito</groupId> | 302 | <groupId>org.mockito</groupId> |
294 | <artifactId>mockito-core</artifactId> | 303 | <artifactId>mockito-core</artifactId> |
295 | <scope>test</scope> | 304 | <scope>test</scope> |
@@ -18,8 +18,8 @@ | @@ -18,8 +18,8 @@ | ||
18 | "resources": [], | 18 | "resources": [], |
19 | "templateHtml": "<div style=\"height: 100%; overflow-y: auto;\" id=\"device-terminal\"></div>", | 19 | "templateHtml": "<div style=\"height: 100%; overflow-y: auto;\" id=\"device-terminal\"></div>", |
20 | "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n\n", | 20 | "templateCss": ".cmd .cursor.blink {\n -webkit-animation-name: terminal-underline;\n -moz-animation-name: terminal-underline;\n -ms-animation-name: terminal-underline;\n animation-name: terminal-underline;\n}\n.terminal .inverted, .cmd .inverted {\n border-bottom-color: #aaa;\n}\n\n", |
21 | - "controllerScript": "var requestTimeout = 500;\nvar requestPersistent = false;\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.requestPersistent) {\n requestPersistent = self.ctx.settings.requestPersistent;\n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = uuidv4();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var spaceIndex = localCommand.indexOf(' ');\n if (spaceIndex === -1 && !localCommand.length) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n } else {\n var params;\n if (spaceIndex === -1) {\n spaceIndex = localCommand.length;\n }\n var name = localCommand.substr(0, spaceIndex);\n var args = localCommand.substr(spaceIndex + 1);\n if (args.length) {\n try {\n params = JSON.parse(args);\n } catch (e) {\n params = args;\n }\n }\n performRpc(this, name, params, requestUUID);\n }\n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' <method> [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1:]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2:]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": 2, \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestPersistent, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\n\nfunction uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n \nself.onDestroy = function() {\n}", | ||
22 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"requestPersistent\"\n ]\n}", | 21 | + "controllerScript": "var requestTimeout = 500;\nvar requestPersistent = false;\nvar persistentPollingInterval = 5000;\n\nself.onInit = function() {\n var subscription = self.ctx.defaultSubscription;\n var rpcEnabled = subscription.rpcEnabled;\n var deviceName = 'Simulated';\n var prompt;\n if (subscription.targetDeviceName && subscription.targetDeviceName.length) {\n deviceName = subscription.targetDeviceName;\n }\n if (self.ctx.settings.requestTimeout) {\n requestTimeout = self.ctx.settings.requestTimeout;\n }\n if (self.ctx.settings.requestPersistent) {\n requestPersistent = self.ctx.settings.requestPersistent;\n }\n if (self.ctx.settings.persistentPollingInterval) {\n persistentPollingInterval = self.ctx.settings.persistentPollingInterval;\n }\n var greetings = 'Welcome to ThingsBoard RPC debug terminal.\\n\\n';\n if (!rpcEnabled) {\n greetings += 'Target device is not set!\\n\\n';\n prompt = '';\n } else {\n greetings += 'Current target device for RPC commands: [[b;#fff;]' + deviceName + ']\\n\\n';\n greetings += 'Please type [[b;#fff;]\\'help\\'] to see usage.\\n';\n prompt = '[[b;#8bc34a;]' + deviceName +']> ';\n }\n \n var terminal = $('#device-terminal', self.ctx.$container).terminal(\n function(command) {\n if (command !== '') {\n try {\n var localCommand = command.trim();\n var requestUUID = uuidv4();\n if (localCommand === 'help') {\n printUsage(this);\n } else {\n var spaceIndex = localCommand.indexOf(' ');\n if (spaceIndex === -1 && !localCommand.length) {\n this.error(\"Wrong number of arguments!\");\n this.echo(' ');\n } else {\n var params;\n if (spaceIndex === -1) {\n spaceIndex = localCommand.length;\n }\n var name = localCommand.substr(0, spaceIndex);\n var args = localCommand.substr(spaceIndex + 1);\n if (args.length) {\n try {\n params = JSON.parse(args);\n } catch (e) {\n params = args;\n }\n }\n performRpc(this, name, params, requestUUID);\n }\n }\n } catch(e) {\n this.error(new String(e));\n }\n } else {\n this.echo('');\n }\n }, {\n greetings: greetings,\n prompt: prompt,\n enabled: rpcEnabled\n });\n \n if (!rpcEnabled) {\n terminal.error('No RPC target detected!').pause();\n }\n}\n\n\nfunction printUsage(terminal) {\n var commandsListText = '\\n[[b;#fff;]Usage:]\\n';\n commandsListText += ' <method> [params body]]\\n\\n';\n commandsListText += '[[b;#fff;]Example 1:]\\n'; \n commandsListText += ' myRemoteMethod1 myText\\n\\n'; \n commandsListText += '[[b;#fff;]Example 2:]\\n'; \n commandsListText += ' myOtherRemoteMethod \"{\\\\\"key1\\\\\": 2, \\\\\"key2\\\\\": \\\\\"myVal\\\\\"}\"\\n'; \n terminal.echo(new String(commandsListText));\n}\n\n\nfunction performRpc(terminal, method, params, requestUUID) {\n terminal.pause();\n self.ctx.controlApi.sendTwoWayCommand(method, params, requestTimeout, requestPersistent, persistentPollingInterval, requestUUID).subscribe(\n function success(responseBody) {\n terminal.echo(JSON.stringify(responseBody));\n terminal.echo(' ');\n terminal.resume();\n },\n function fail() {\n var errorText = self.ctx.defaultSubscription.rpcErrorText;\n terminal.error(errorText);\n terminal.echo(' ');\n terminal.resume();\n }\n );\n}\n\n\nfunction uuidv4() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n \nself.onDestroy = function() {\n self.ctx.controlApi.completedCommand();\n}", |
22 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n }\n ]\n}", | ||
23 | "dataKeySettingsSchema": "{}\n", | 23 | "dataKeySettingsSchema": "{}\n", |
24 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 24 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":true,\"backgroundColor\":\"#010101\",\"color\":\"rgba(255, 254, 254, 0.87)\",\"padding\":\"0px\",\"settings\":{\"parseGpioStatusFunction\":\"return body[pin] === true;\",\"gpioStatusChangeRequest\":{\"method\":\"setGpioStatus\",\"paramsBody\":\"{\\n \\\"pin\\\": \\\"{$pin}\\\",\\n \\\"enabled\\\": \\\"{$enabled}\\\"\\n}\"},\"requestTimeout\":500,\"switchPanelBackgroundColor\":\"#b71c1c\",\"gpioStatusRequest\":{\"method\":\"getGpioStatus\",\"paramsBody\":\"{}\"},\"gpioList\":[{\"pin\":1,\"label\":\"GPIO 1\",\"row\":0,\"col\":0,\"_uniqueKey\":0},{\"pin\":2,\"label\":\"GPIO 2\",\"row\":0,\"col\":1,\"_uniqueKey\":1},{\"pin\":3,\"label\":\"GPIO 3\",\"row\":1,\"col\":0,\"_uniqueKey\":2}]},\"title\":\"RPC debug terminal\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
25 | } | 25 | } |
@@ -55,7 +55,7 @@ | @@ -55,7 +55,7 @@ | ||
55 | "templateHtml": "<tb-knob [ctx]='ctx'></tb-knob>", | 55 | "templateHtml": "<tb-knob [ctx]='ctx'></tb-knob>", |
56 | "templateCss": "", | 56 | "templateCss": "", |
57 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", | 57 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", |
58 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"number\",\n \"default\": 50\n },\n \"title\": {\n \"title\": \"Knob title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"minValue\", \"maxValue\", \"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"minValue\",\n \"maxValue\",\n \"initialValue\",\n \"title\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\"\n ]\n}", | 58 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"number\",\n \"default\": 50\n },\n \"title\": {\n \"title\": \"Knob title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n }\n },\n \"required\": [\"minValue\", \"maxValue\", \"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"minValue\",\n \"maxValue\",\n \"initialValue\",\n \"title\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n }\n ]\n}", |
59 | "dataKeySettingsSchema": "{}\n", | 59 | "dataKeySettingsSchema": "{}\n", |
60 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"maxValue\":100,\"initialValue\":50,\"minValue\":0,\"title\":\"Knob control\",\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\"},\"title\":\"Knob Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 60 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"maxValue\":100,\"initialValue\":50,\"minValue\":0,\"title\":\"Knob control\",\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\"},\"title\":\"Knob Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
61 | } | 61 | } |
@@ -73,7 +73,7 @@ | @@ -73,7 +73,7 @@ | ||
73 | "templateHtml": "<tb-switch [ctx]='ctx'></tb-switch>", | 73 | "templateHtml": "<tb-switch [ctx]='ctx'></tb-switch>", |
74 | "templateCss": "", | 74 | "templateCss": "", |
75 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", | 75 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", |
76 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showOnOffLabels\": {\n \"title\": \"Show on/off labels\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"showOnOffLabels\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", | 76 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showOnOffLabels\": {\n \"title\": \"Show on/off labels\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"showOnOffLabels\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n }\n ]\n}", |
77 | "dataKeySettingsSchema": "{}\n", | 77 | "dataKeySettingsSchema": "{}\n", |
78 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Switch control\"},\"title\":\"Switch Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 78 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Switch control\"},\"title\":\"Switch Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
79 | } | 79 | } |
@@ -91,7 +91,7 @@ | @@ -91,7 +91,7 @@ | ||
91 | "templateHtml": "<tb-round-switch [ctx]='ctx'></tb-round-switch>", | 91 | "templateHtml": "<tb-round-switch [ctx]='ctx'></tb-round-switch>", |
92 | "templateCss": "", | 92 | "templateCss": "", |
93 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", | 93 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", |
94 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", | 94 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n }\n ]\n}", |
95 | "dataKeySettingsSchema": "{}\n", | 95 | "dataKeySettingsSchema": "{}\n", |
96 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"title\":\"Round switch\",\"retrieveValueMethod\":\"rpc\",\"valueKey\":\"value\",\"parseValueFunction\":\"return data ? true : false;\",\"convertValueFunction\":\"return value;\"},\"title\":\"Round switch\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 96 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"title\":\"Round switch\",\"retrieveValueMethod\":\"rpc\",\"valueKey\":\"value\",\"parseValueFunction\":\"return data ? true : false;\",\"convertValueFunction\":\"return value;\"},\"title\":\"Round switch\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
97 | } | 97 | } |
@@ -109,7 +109,7 @@ | @@ -109,7 +109,7 @@ | ||
109 | "templateHtml": "<tb-led-indicator [ctx]='ctx'></tb-led-indicator>", | 109 | "templateHtml": "<tb-led-indicator [ctx]='ctx'></tb-led-indicator>", |
110 | "templateCss": "", | 110 | "templateCss": "", |
111 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", | 111 | "controllerScript": "self.onInit = function() {\n}\n\nself.onResize = function() {\n}\n\nself.onDestroy = function() {\n}\n", |
112 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"LED title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"ledColor\": {\n \"title\": \"LED Color\",\n \"type\": \"string\",\n \"default\": \"green\"\n },\n \"performCheckStatus\": {\n \"title\": \"Perform RPC device status check\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"checkStatusMethod\": {\n \"title\": \"RPC check device status method\",\n \"type\": \"string\",\n \"default\": \"checkStatus\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve led status value using method\",\n \"type\": \"string\",\n \"default\": \"attribute\"\n },\n \"valueAttribute\": {\n \"title\": \"Device attribute/timeseries containing led status value\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse led status value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"valueAttribute\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"ledColor\",\n \"type\": \"color\"\n },\n \"performCheckStatus\",\n \"checkStatusMethod\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueAttribute\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", | 112 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"LED title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"ledColor\": {\n \"title\": \"LED Color\",\n \"type\": \"string\",\n \"default\": \"green\"\n },\n \"performCheckStatus\": {\n \"title\": \"Perform RPC device status check\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"checkStatusMethod\": {\n \"title\": \"RPC check device status method\",\n \"type\": \"string\",\n \"default\": \"checkStatus\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve led status value using method\",\n \"type\": \"string\",\n \"default\": \"attribute\"\n },\n \"valueAttribute\": {\n \"title\": \"Device attribute/timeseries containing led status value\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse led status value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n }\n },\n \"required\": [\"valueAttribute\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"ledColor\",\n \"type\": \"color\"\n },\n \"performCheckStatus\",\n \"checkStatusMethod\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueAttribute\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n }\n ]\n}", |
113 | "dataKeySettingsSchema": "{}\n", | 113 | "dataKeySettingsSchema": "{}\n", |
114 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":true,\"title\":\"Led indicator\",\"ledColor\":\"#4caf50\",\"valueAttribute\":\"value\",\"retrieveValueMethod\":\"attribute\",\"parseValueFunction\":\"return data ? true : false;\",\"performCheckStatus\":true,\"checkStatusMethod\":\"checkStatus\"},\"title\":\"Led indicator\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 114 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":true,\"title\":\"Led indicator\",\"ledColor\":\"#4caf50\",\"valueAttribute\":\"value\",\"retrieveValueMethod\":\"attribute\",\"parseValueFunction\":\"return data ? true : false;\",\"performCheckStatus\":true,\"checkStatusMethod\":\"checkStatus\"},\"title\":\"Led indicator\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
115 | } | 115 | } |
@@ -126,8 +126,8 @@ | @@ -126,8 +126,8 @@ | ||
126 | "resources": [], | 126 | "resources": [], |
127 | "templateHtml": "<div class=\"tb-rpc-button\" fxLayout=\"column\">\n <div fxFlex=\"20\" class=\"title-container\" fxLayout=\"row\"\n fxLayoutAlign=\"center center\" [fxShow]=\"showTitle\">\n <span class=\"button-title\">{{title}}</span>\n </div>\n <div fxFlex=\"{{showTitle ? 80 : 100}}\" [ngStyle]=\"{paddingTop: showTitle ? '5px': '10px'}\"\n class=\"button-container\" fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <div>\n <button mat-button (click)=\"sendCommand()\"\n [class.mat-raised-button]=\"styleButton?.isRaised\"\n [color]=\"styleButton?.isPrimary ? 'primary' : ''\"\n [ngStyle]=\"customStyle\">\n {{buttonLable}}\n </button>\n </div>\n </div>\n <div class=\"error-container\" [ngStyle]=\"{'background': error?.length ? 'rgba(255,255,255,0.25)' : 'none'}\"\n fxLayout=\"row\" fxLayoutAlign=\"center center\">\n <span class=\"button-error\">{{ error }}</span>\n </div>\n</div>", | 127 | "templateHtml": "<div class=\"tb-rpc-button\" fxLayout=\"column\">\n <div fxFlex=\"20\" class=\"title-container\" fxLayout=\"row\"\n fxLayoutAlign=\"center center\" [fxShow]=\"showTitle\">\n <span class=\"button-title\">{{title}}</span>\n </div>\n <div fxFlex=\"{{showTitle ? 80 : 100}}\" [ngStyle]=\"{paddingTop: showTitle ? '5px': '10px'}\"\n class=\"button-container\" fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <div>\n <button mat-button (click)=\"sendCommand()\"\n [class.mat-raised-button]=\"styleButton?.isRaised\"\n [color]=\"styleButton?.isPrimary ? 'primary' : ''\"\n [ngStyle]=\"customStyle\">\n {{buttonLable}}\n </button>\n </div>\n </div>\n <div class=\"error-container\" [ngStyle]=\"{'background': error?.length ? 'rgba(255,255,255,0.25)' : 'none'}\"\n fxLayout=\"row\" fxLayoutAlign=\"center center\">\n <span class=\"button-error\">{{ error }}</span>\n </div>\n</div>", |
128 | "templateCss": ".tb-rpc-button {\n width: 100%;\n height: 100%;\n}\n\n.tb-rpc-button .title-container {\n font-weight: 500;\n white-space: nowrap;\n margin: 10px 0;\n}\n\n.tb-rpc-button .button-container div{\n min-width: 80%\n}\n\n.tb-rpc-button .button-container .mat-button{\n width: 100%;\n margin: 0;\n}\n\n.tb-rpc-button .error-container {\n position: absolute;\n top: 2%;\n right: 0;\n left: 0;\n z-index: 4;\n height: 14px;\n}\n\n.tb-rpc-button .error-container .button-error {\n color: #ff3315;\n white-space: nowrap;\n}", | 128 | "templateCss": ".tb-rpc-button {\n width: 100%;\n height: 100%;\n}\n\n.tb-rpc-button .title-container {\n font-weight: 500;\n white-space: nowrap;\n margin: 10px 0;\n}\n\n.tb-rpc-button .button-container div{\n min-width: 80%\n}\n\n.tb-rpc-button .button-container .mat-button{\n width: 100%;\n margin: 0;\n}\n\n.tb-rpc-button .error-container {\n position: absolute;\n top: 2%;\n right: 0;\n left: 0;\n z-index: 4;\n height: 14px;\n}\n\n.tb-rpc-button .error-container .button-error {\n color: #ff3315;\n white-space: nowrap;\n}", |
129 | - "controllerScript": "self.onInit = function() {\n self.ctx.ngZone.run(function() {\n init(); \n self.ctx.detectChanges();\n });\n};\n\nfunction init() {\n let rpcEnabled = self.ctx.defaultSubscription.rpcEnabled;\n\n self.ctx.$scope.buttonLable = self.ctx.settings.buttonText;\n self.ctx.$scope.showTitle = self.ctx.settings.title &&\n self.ctx.settings.title.length ? true : false;\n self.ctx.$scope.title = self.ctx.settings.title;\n self.ctx.$scope.styleButton = self.ctx.settings.styleButton;\n\n if (self.ctx.settings.styleButton.isPrimary ===\n false) {\n self.ctx.$scope.customStyle = {\n 'background-color': self.ctx.$scope.styleButton.bgColor,\n 'color': self.ctx.$scope.styleButton.textColor\n };\n }\n\n if (!rpcEnabled) {\n self.ctx.$scope.error =\n 'Target device is not set!';\n }\n\n self.ctx.$scope.sendCommand = function() {\n var rpcMethod = self.ctx.settings.methodName;\n var rpcParams = self.ctx.settings.methodParams;\n var timeout = self.ctx.settings.requestTimeout;\n var oneWayElseTwoWay = self.ctx.settings.oneWayElseTwoWay ?\n true : false;\n\n var commandPromise;\n if (oneWayElseTwoWay) {\n commandPromise = self.ctx.controlApi.sendOneWayCommand(\n rpcMethod, rpcParams, timeout);\n } else {\n commandPromise = self.ctx.controlApi.sendTwoWayCommand(\n rpcMethod, rpcParams, timeout);\n }\n commandPromise.subscribe(\n function success() {\n self.ctx.$scope.error = \"\";\n self.ctx.detectChanges();\n },\n function fail(rejection) {\n if (self.ctx.settings.showError) {\n self.ctx.$scope.error =\n rejection.status + \": \" +\n rejection.statusText;\n self.ctx.detectChanges();\n }\n }\n );\n };\n}\n", | ||
130 | - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"title\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"buttonText\": {\n \"title\": \"Button label\",\n \"type\": \"string\",\n \"default\": \"Send RPC\"\n },\n \"oneWayElseTwoWay\": {\n \"title\": \"Is One Way Command\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showError\": {\n \"title\": \"Show RPC command execution error\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"methodName\": {\n \"title\": \"RPC method\",\n \"type\": \"string\",\n \"default\": \"rpcCommand\"\n },\n \"methodParams\": {\n \"title\": \"RPC method params\",\n \"type\": \"string\",\n \"default\": \"{}\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 5000\n },\n \"styleButton\": {\n \"type\": \"object\",\n \"title\": \"Button Style\",\n \"properties\": {\n \"isRaised\": {\n \"type\": \"boolean\",\n \"title\": \"Raised\",\n \"default\": true\n },\n \"isPrimary\": {\n \"type\": \"boolean\",\n \"title\": \"Primary color\",\n \"default\": false\n },\n \"bgColor\": {\n \"type\": \"string\",\n \"title\": \"Button background color\",\n \"default\": null\n },\n \"textColor\": {\n \"type\": \"string\",\n \"title\": \"Button text color\",\n \"default\": null\n }\n }\n },\n \"required\": []\n }\n },\n \"form\": [\n \"title\",\n \"buttonText\",\n \"oneWayElseTwoWay\",\n \"showError\",\n \"methodName\",\n {\n \"key\": \"methodParams\",\n \"type\": \"json\"\n },\n \"requestTimeout\",\n {\n \"key\": \"styleButton\",\n \"items\": [\n \"styleButton.isRaised\",\n \"styleButton.isPrimary\",\n {\n \"key\": \"styleButton.bgColor\",\n \"type\": \"color\"\n },\n {\n \"key\": \"styleButton.textColor\",\n \"type\": \"color\"\n }\n ]\n }\n ]\n\n}", | 129 | + "controllerScript": "var requestPersistent = false;\nvar persistentPollingInterval = 5000;\n\nself.onInit = function() {\n if (self.ctx.settings.requestPersistent) {\n requestPersistent = self.ctx.settings.requestPersistent;\n }\n if (self.ctx.settings.persistentPollingInterval) {\n persistentPollingInterval = self.ctx.settings.persistentPollingInterval;\n }\n \n self.ctx.ngZone.run(function() {\n init(); \n self.ctx.detectChanges();\n });\n};\n\nfunction init() {\n let rpcEnabled = self.ctx.defaultSubscription.rpcEnabled;\n\n self.ctx.$scope.buttonLable = self.ctx.settings.buttonText;\n self.ctx.$scope.showTitle = self.ctx.settings.title &&\n self.ctx.settings.title.length ? true : false;\n self.ctx.$scope.title = self.ctx.settings.title;\n self.ctx.$scope.styleButton = self.ctx.settings.styleButton;\n\n if (self.ctx.settings.styleButton.isPrimary ===\n false) {\n self.ctx.$scope.customStyle = {\n 'background-color': self.ctx.$scope.styleButton.bgColor,\n 'color': self.ctx.$scope.styleButton.textColor\n };\n }\n\n if (!rpcEnabled) {\n self.ctx.$scope.error =\n 'Target device is not set!';\n }\n\n self.ctx.$scope.sendCommand = function() {\n var rpcMethod = self.ctx.settings.methodName;\n var rpcParams = self.ctx.settings.methodParams;\n var timeout = self.ctx.settings.requestTimeout;\n var oneWayElseTwoWay = self.ctx.settings.oneWayElseTwoWay ?\n true : false;\n\n var commandPromise;\n if (oneWayElseTwoWay) {\n commandPromise = self.ctx.controlApi.sendOneWayCommand(\n rpcMethod, rpcParams, timeout, requestPersistent, persistentPollingInterval);\n } else {\n commandPromise = self.ctx.controlApi.sendTwoWayCommand(\n rpcMethod, rpcParams, timeout, requestPersistent, persistentPollingInterval);\n }\n commandPromise.subscribe(\n function success() {\n self.ctx.$scope.error = \"\";\n self.ctx.detectChanges();\n },\n function fail(rejection) {\n if (self.ctx.settings.showError) {\n self.ctx.$scope.error =\n rejection.status + \": \" +\n rejection.statusText;\n self.ctx.detectChanges();\n }\n }\n );\n };\n}\n\nself.onDestroy = function() {\n self.ctx.controlApi.completedCommand();\n}\n", |
130 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"title\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"buttonText\": {\n \"title\": \"Button label\",\n \"type\": \"string\",\n \"default\": \"Send RPC\"\n },\n \"oneWayElseTwoWay\": {\n \"title\": \"Is One Way Command\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showError\": {\n \"title\": \"Show RPC command execution error\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"methodName\": {\n \"title\": \"RPC method\",\n \"type\": \"string\",\n \"default\": \"rpcCommand\"\n },\n \"methodParams\": {\n \"title\": \"RPC method params\",\n \"type\": \"string\",\n \"default\": \"{}\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 5000\n },\n \"requestPersistent\": {\n \"title\": \"RPC request persistent\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"persistentPollingInterval\": {\n \"title\": \"Polling interval in milliseconds to get persistent RPC command response\",\n \"type\": \"number\",\n \"default\": 5000,\n \"minimum\": 1000\n },\n \"styleButton\": {\n \"type\": \"object\",\n \"title\": \"Button Style\",\n \"properties\": {\n \"isRaised\": {\n \"type\": \"boolean\",\n \"title\": \"Raised\",\n \"default\": true\n },\n \"isPrimary\": {\n \"type\": \"boolean\",\n \"title\": \"Primary color\",\n \"default\": false\n },\n \"bgColor\": {\n \"type\": \"string\",\n \"title\": \"Button background color\",\n \"default\": null\n },\n \"textColor\": {\n \"type\": \"string\",\n \"title\": \"Button text color\",\n \"default\": null\n }\n }\n },\n \"required\": []\n }\n },\n \"form\": [\n \"title\",\n \"buttonText\",\n \"oneWayElseTwoWay\",\n \"showError\",\n \"methodName\",\n {\n \"key\": \"methodParams\",\n \"type\": \"json\"\n },\n \"requestTimeout\",\n \"requestPersistent\",\n {\n \"key\": \"persistentPollingInterval\",\n \"condition\": \"model.requestPersistent === true\"\n },\n {\n \"key\": \"styleButton\",\n \"items\": [\n \"styleButton.isRaised\",\n \"styleButton.isPrimary\",\n {\n \"key\": \"styleButton.bgColor\",\n \"type\": \"color\"\n },\n {\n \"key\": \"styleButton.textColor\",\n \"type\": \"color\"\n }\n ]\n }\n ]\n\n}", | ||
131 | "dataKeySettingsSchema": "{}\n", | 131 | "dataKeySettingsSchema": "{}\n", |
132 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":5000,\"oneWayElseTwoWay\":true,\"buttonText\":\"Send RPC\",\"styleButton\":{\"isRaised\":true,\"isPrimary\":false},\"methodName\":\"rpcCommand\",\"methodParams\":\"{}\"},\"title\":\"RPC Button\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 132 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#e6e7e8\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":5000,\"oneWayElseTwoWay\":true,\"buttonText\":\"Send RPC\",\"styleButton\":{\"isRaised\":true,\"isPrimary\":false},\"methodName\":\"rpcCommand\",\"methodParams\":\"{}\"},\"title\":\"RPC Button\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
133 | } | 133 | } |
@@ -209,6 +209,7 @@ CREATE TABLE IF NOT EXISTS rpc ( | @@ -209,6 +209,7 @@ CREATE TABLE IF NOT EXISTS rpc ( | ||
209 | expiration_time bigint NOT NULL, | 209 | expiration_time bigint NOT NULL, |
210 | request varchar(10000000) NOT NULL, | 210 | request varchar(10000000) NOT NULL, |
211 | response varchar(10000000), | 211 | response varchar(10000000), |
212 | + additional_info varchar(10000000), | ||
212 | status varchar(255) NOT NULL | 213 | status varchar(255) NOT NULL |
213 | ); | 214 | ); |
214 | 215 |
@@ -81,7 +81,7 @@ import org.thingsboard.server.service.executors.ExternalCallExecutorService; | @@ -81,7 +81,7 @@ import org.thingsboard.server.service.executors.ExternalCallExecutorService; | ||
81 | import org.thingsboard.server.service.executors.SharedEventLoopGroupService; | 81 | import org.thingsboard.server.service.executors.SharedEventLoopGroupService; |
82 | import org.thingsboard.server.service.mail.MailExecutorService; | 82 | import org.thingsboard.server.service.mail.MailExecutorService; |
83 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 83 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
84 | -import org.thingsboard.server.service.queue.TbClusterService; | 84 | +import org.thingsboard.server.cluster.TbClusterService; |
85 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | 85 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; |
86 | import org.thingsboard.server.service.rpc.TbRpcService; | 86 | import org.thingsboard.server.service.rpc.TbRpcService; |
87 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | 87 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; |
@@ -55,7 +55,7 @@ public class AppActor extends ContextAwareActor { | @@ -55,7 +55,7 @@ public class AppActor extends ContextAwareActor { | ||
55 | private final TbTenantProfileCache tenantProfileCache; | 55 | private final TbTenantProfileCache tenantProfileCache; |
56 | private final TenantService tenantService; | 56 | private final TenantService tenantService; |
57 | private final Set<TenantId> deletedTenants; | 57 | private final Set<TenantId> deletedTenants; |
58 | - private boolean ruleChainsInitialized; | 58 | + private volatile boolean ruleChainsInitialized; |
59 | 59 | ||
60 | private AppActor(ActorSystemContext systemContext) { | 60 | private AppActor(ActorSystemContext systemContext) { |
61 | super(systemContext); | 61 | super(systemContext); |
@@ -69,7 +69,7 @@ public class AppActor extends ContextAwareActor { | @@ -69,7 +69,7 @@ public class AppActor extends ContextAwareActor { | ||
69 | if (!ruleChainsInitialized) { | 69 | if (!ruleChainsInitialized) { |
70 | initTenantActors(); | 70 | initTenantActors(); |
71 | ruleChainsInitialized = true; | 71 | ruleChainsInitialized = true; |
72 | - if (msg.getMsgType() != MsgType.APP_INIT_MSG) { | 72 | + if (msg.getMsgType() != MsgType.APP_INIT_MSG && msg.getMsgType() != MsgType.PARTITION_CHANGE_MSG) { |
73 | log.warn("Rule Chains initialized by unexpected message: {}", msg); | 73 | log.warn("Rule Chains initialized by unexpected message: {}", msg); |
74 | } | 74 | } |
75 | } | 75 | } |
@@ -95,6 +95,7 @@ public class AppActor extends ContextAwareActor { | @@ -95,6 +95,7 @@ public class AppActor extends ContextAwareActor { | ||
95 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 95 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
96 | case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 96 | case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
97 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 97 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
98 | + case REMOVE_RPC_TO_DEVICE_ACTOR_MSG: | ||
98 | onToDeviceActorMsg((TenantAwareMsg) msg, true); | 99 | onToDeviceActorMsg((TenantAwareMsg) msg, true); |
99 | break; | 100 | break; |
100 | case EDGE_EVENT_UPDATE_TO_EDGE_SESSION_MSG: | 101 | case EDGE_EVENT_UPDATE_TO_EDGE_SESSION_MSG: |
@@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
28 | import org.thingsboard.server.common.msg.TbActorMsg; | 28 | import org.thingsboard.server.common.msg.TbActorMsg; |
29 | import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; | 29 | import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; |
30 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; | 30 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; |
31 | +import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; | ||
31 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 32 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
32 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | 33 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; |
33 | 34 | ||
@@ -84,6 +85,9 @@ public class DeviceActor extends ContextAwareActor { | @@ -84,6 +85,9 @@ public class DeviceActor extends ContextAwareActor { | ||
84 | case DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG: | 85 | case DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG: |
85 | processor.processEdgeUpdate((DeviceEdgeUpdateMsg) msg); | 86 | processor.processEdgeUpdate((DeviceEdgeUpdateMsg) msg); |
86 | break; | 87 | break; |
88 | + case REMOVE_RPC_TO_DEVICE_ACTOR_MSG: | ||
89 | + processor.processRemoveRpc(ctx, (RemoveRpcActorMsg) msg); | ||
90 | + break; | ||
87 | default: | 91 | default: |
88 | return false; | 92 | return false; |
89 | } | 93 | } |
@@ -26,7 +26,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -26,7 +26,7 @@ import lombok.extern.slf4j.Slf4j; | ||
26 | import org.apache.commons.collections.CollectionUtils; | 26 | import org.apache.commons.collections.CollectionUtils; |
27 | import org.thingsboard.common.util.JacksonUtil; | 27 | import org.thingsboard.common.util.JacksonUtil; |
28 | import org.thingsboard.common.util.LinkedHashMapRemoveEldest; | 28 | import org.thingsboard.common.util.LinkedHashMapRemoveEldest; |
29 | -import org.thingsboard.rule.engine.api.RpcError; | 29 | +import org.thingsboard.server.common.data.rpc.RpcError; |
30 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; | 30 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; |
31 | import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; | 31 | import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; |
32 | import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; | 32 | import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; |
@@ -86,8 +86,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; | @@ -86,8 +86,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; | ||
86 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto; | 86 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto; |
87 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; | 87 | import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; |
88 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; | 88 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; |
89 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 89 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; |
90 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; | 90 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; |
91 | +import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; | ||
91 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 92 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
92 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | 93 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; |
93 | 94 | ||
@@ -97,11 +98,9 @@ import java.util.Arrays; | @@ -97,11 +98,9 @@ import java.util.Arrays; | ||
97 | import java.util.Collections; | 98 | import java.util.Collections; |
98 | import java.util.HashMap; | 99 | import java.util.HashMap; |
99 | import java.util.HashSet; | 100 | import java.util.HashSet; |
100 | -import java.util.LinkedHashMap; | ||
101 | import java.util.List; | 101 | import java.util.List; |
102 | import java.util.Map; | 102 | import java.util.Map; |
103 | import java.util.Objects; | 103 | import java.util.Objects; |
104 | -import java.util.Optional; | ||
105 | import java.util.Set; | 104 | import java.util.Set; |
106 | import java.util.UUID; | 105 | import java.util.UUID; |
107 | import java.util.function.Consumer; | 106 | import java.util.function.Consumer; |
@@ -236,6 +235,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -236,6 +235,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
236 | rpc.setExpirationTime(request.getExpirationTime()); | 235 | rpc.setExpirationTime(request.getExpirationTime()); |
237 | rpc.setRequest(JacksonUtil.valueToTree(request)); | 236 | rpc.setRequest(JacksonUtil.valueToTree(request)); |
238 | rpc.setStatus(status); | 237 | rpc.setStatus(status); |
238 | + rpc.setAdditionalInfo(JacksonUtil.valueToTree(request.getAdditionalInfo())); | ||
239 | return systemContext.getTbRpcService().save(tenantId, rpc); | 239 | return systemContext.getTbRpcService().save(tenantId, rpc); |
240 | } | 240 | } |
241 | 241 | ||
@@ -264,6 +264,21 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -264,6 +264,21 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
267 | + void processRemoveRpc(TbActorCtx context, RemoveRpcActorMsg msg) { | ||
268 | + log.debug("[{}] Processing remove rpc command", msg.getRequestId()); | ||
269 | + Integer requestId = null; | ||
270 | + for (Map.Entry<Integer, ToDeviceRpcRequestMetadata> entry : toDeviceRpcPendingMap.entrySet()) { | ||
271 | + if (entry.getValue().getMsg().getMsg().getId().equals(msg.getRequestId())) { | ||
272 | + requestId = entry.getKey(); | ||
273 | + break; | ||
274 | + } | ||
275 | + } | ||
276 | + | ||
277 | + if (requestId != null) { | ||
278 | + toDeviceRpcPendingMap.remove(requestId); | ||
279 | + } | ||
280 | + } | ||
281 | + | ||
267 | private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { | 282 | private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { |
268 | toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); | 283 | toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); |
269 | DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); | 284 | DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); |
@@ -383,11 +398,11 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -383,11 +398,11 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
383 | } | 398 | } |
384 | 399 | ||
385 | private void reportSessionOpen() { | 400 | private void reportSessionOpen() { |
386 | - systemContext.getDeviceStateService().onDeviceConnect(deviceId); | 401 | + systemContext.getDeviceStateService().onDeviceConnect(tenantId, deviceId); |
387 | } | 402 | } |
388 | 403 | ||
389 | private void reportSessionClose() { | 404 | private void reportSessionClose() { |
390 | - systemContext.getDeviceStateService().onDeviceDisconnect(deviceId); | 405 | + systemContext.getDeviceStateService().onDeviceDisconnect(tenantId, deviceId); |
391 | } | 406 | } |
392 | 407 | ||
393 | private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { | 408 | private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { |
@@ -586,13 +601,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -586,13 +601,13 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
586 | log.debug("[{}] Received duplicate session open event [{}]", deviceId, sessionId); | 601 | log.debug("[{}] Received duplicate session open event [{}]", deviceId, sessionId); |
587 | return; | 602 | return; |
588 | } | 603 | } |
589 | - log.info("[{}] Processing new session [{}]. Current sessions size {}", deviceId, sessionId, sessions.size()); | 604 | + log.debug("[{}] Processing new session [{}]. Current sessions size {}", deviceId, sessionId, sessions.size()); |
590 | 605 | ||
591 | sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId()))); | 606 | sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId()))); |
592 | if (sessions.size() == 1) { | 607 | if (sessions.size() == 1) { |
593 | reportSessionOpen(); | 608 | reportSessionOpen(); |
594 | } | 609 | } |
595 | - systemContext.getDeviceStateService().onDeviceActivity(deviceId, System.currentTimeMillis()); | 610 | + systemContext.getDeviceStateService().onDeviceActivity(tenantId, deviceId, System.currentTimeMillis()); |
596 | dumpSessions(); | 611 | dumpSessions(); |
597 | } else if (msg.getEvent() == SessionEvent.CLOSED) { | 612 | } else if (msg.getEvent() == SessionEvent.CLOSED) { |
598 | log.debug("[{}] Canceling subscriptions for closed session [{}]", deviceId, sessionId); | 613 | log.debug("[{}] Canceling subscriptions for closed session [{}]", deviceId, sessionId); |
@@ -622,7 +637,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -622,7 +637,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
622 | if (subscriptionInfo.getRpcSubscription()) { | 637 | if (subscriptionInfo.getRpcSubscription()) { |
623 | rpcSubscriptions.putIfAbsent(sessionId, sessionMD.getSessionInfo()); | 638 | rpcSubscriptions.putIfAbsent(sessionId, sessionMD.getSessionInfo()); |
624 | } | 639 | } |
625 | - systemContext.getDeviceStateService().onDeviceActivity(deviceId, subscriptionInfo.getLastActivityTime()); | 640 | + systemContext.getDeviceStateService().onDeviceActivity(tenantId, deviceId, subscriptionInfo.getLastActivityTime()); |
626 | dumpSessions(); | 641 | dumpSessions(); |
627 | } | 642 | } |
628 | 643 | ||
@@ -729,18 +744,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | @@ -729,18 +744,8 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { | ||
729 | edgeEvent.setBody(body); | 744 | edgeEvent.setBody(body); |
730 | 745 | ||
731 | edgeEvent.setEdgeId(edgeId); | 746 | edgeEvent.setEdgeId(edgeId); |
732 | - ListenableFuture<EdgeEvent> future = systemContext.getEdgeEventService().saveAsync(edgeEvent); | ||
733 | - Futures.addCallback(future, new FutureCallback<EdgeEvent>() { | ||
734 | - @Override | ||
735 | - public void onSuccess(EdgeEvent result) { | ||
736 | - systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId); | ||
737 | - } | ||
738 | - | ||
739 | - @Override | ||
740 | - public void onFailure(Throwable t) { | ||
741 | - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t); | ||
742 | - } | ||
743 | - }, systemContext.getDbCallbackExecutor()); | 747 | + systemContext.getEdgeEventService().save(edgeEvent); |
748 | + systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId); | ||
744 | } | 749 | } |
745 | 750 | ||
746 | private List<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) { | 751 | private List<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) { |
@@ -33,6 +33,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; | @@ -33,6 +33,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; | ||
33 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; | 33 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; |
34 | import org.thingsboard.server.actors.ActorSystemContext; | 34 | import org.thingsboard.server.actors.ActorSystemContext; |
35 | import org.thingsboard.server.actors.TbActorRef; | 35 | import org.thingsboard.server.actors.TbActorRef; |
36 | +import org.thingsboard.server.cluster.TbClusterService; | ||
36 | import org.thingsboard.server.common.data.Customer; | 37 | import org.thingsboard.server.common.data.Customer; |
37 | import org.thingsboard.server.common.data.DataConstants; | 38 | import org.thingsboard.server.common.data.DataConstants; |
38 | import org.thingsboard.server.common.data.Device; | 39 | import org.thingsboard.server.common.data.Device; |
@@ -454,6 +455,11 @@ class DefaultTbContext implements TbContext { | @@ -454,6 +455,11 @@ class DefaultTbContext implements TbContext { | ||
454 | } | 455 | } |
455 | 456 | ||
456 | @Override | 457 | @Override |
458 | + public TbClusterService getClusterService() { | ||
459 | + return mainCtx.getClusterService(); | ||
460 | + } | ||
461 | + | ||
462 | + @Override | ||
457 | public DashboardService getDashboardService() { | 463 | public DashboardService getDashboardService() { |
458 | return mainCtx.getDashboardService(); | 464 | return mainCtx.getDashboardService(); |
459 | } | 465 | } |
@@ -49,7 +49,7 @@ import org.thingsboard.server.queue.TbQueueCallback; | @@ -49,7 +49,7 @@ import org.thingsboard.server.queue.TbQueueCallback; | ||
49 | import org.thingsboard.server.queue.common.MultipleTbQueueTbMsgCallbackWrapper; | 49 | import org.thingsboard.server.queue.common.MultipleTbQueueTbMsgCallbackWrapper; |
50 | import org.thingsboard.server.queue.common.TbQueueTbMsgCallbackWrapper; | 50 | import org.thingsboard.server.queue.common.TbQueueTbMsgCallbackWrapper; |
51 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; | 51 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; |
52 | -import org.thingsboard.server.service.queue.TbClusterService; | 52 | +import org.thingsboard.server.cluster.TbClusterService; |
53 | 53 | ||
54 | import java.util.ArrayList; | 54 | import java.util.ArrayList; |
55 | import java.util.Collections; | 55 | import java.util.Collections; |
@@ -165,6 +165,7 @@ public class TenantActor extends RuleChainManagerActor { | @@ -165,6 +165,7 @@ public class TenantActor extends RuleChainManagerActor { | ||
165 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 165 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
166 | case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 166 | case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
167 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 167 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
168 | + case REMOVE_RPC_TO_DEVICE_ACTOR_MSG: | ||
168 | onToDeviceActorMsg((DeviceAwareMsg) msg, true); | 169 | onToDeviceActorMsg((DeviceAwareMsg) msg, true); |
169 | break; | 170 | break; |
170 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: | 171 | case RULE_CHAIN_TO_RULE_CHAIN_MSG: |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import com.google.common.util.concurrent.FutureCallback; | ||
20 | +import lombok.extern.slf4j.Slf4j; | ||
21 | +import org.springframework.beans.factory.annotation.Autowired; | ||
22 | +import org.springframework.beans.factory.annotation.Value; | ||
23 | +import org.springframework.http.HttpStatus; | ||
24 | +import org.springframework.http.ResponseEntity; | ||
25 | +import org.springframework.util.StringUtils; | ||
26 | +import org.springframework.web.context.request.async.DeferredResult; | ||
27 | +import org.thingsboard.common.util.JacksonUtil; | ||
28 | +import org.thingsboard.server.common.data.rpc.RpcError; | ||
29 | +import org.thingsboard.server.common.data.DataConstants; | ||
30 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
31 | +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | ||
32 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | ||
33 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
34 | +import org.thingsboard.server.common.data.id.EntityId; | ||
35 | +import org.thingsboard.server.common.data.id.TenantId; | ||
36 | +import org.thingsboard.server.common.data.id.UUIDBased; | ||
37 | +import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; | ||
38 | +import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | ||
39 | +import org.thingsboard.server.queue.util.TbCoreComponent; | ||
40 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
41 | +import org.thingsboard.server.service.rpc.LocalRequestMetaData; | ||
42 | +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | ||
43 | +import org.thingsboard.server.service.security.AccessValidator; | ||
44 | +import org.thingsboard.server.service.security.model.SecurityUser; | ||
45 | +import org.thingsboard.server.service.security.permission.Operation; | ||
46 | +import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity; | ||
47 | + | ||
48 | +import javax.annotation.Nullable; | ||
49 | +import java.util.Optional; | ||
50 | +import java.util.UUID; | ||
51 | + | ||
52 | +/** | ||
53 | + * Created by ashvayka on 22.03.18. | ||
54 | + */ | ||
55 | +@TbCoreComponent | ||
56 | +@Slf4j | ||
57 | +public abstract class AbstractRpcController extends BaseController { | ||
58 | + | ||
59 | + @Autowired | ||
60 | + protected TbCoreDeviceRpcService deviceRpcService; | ||
61 | + | ||
62 | + @Autowired | ||
63 | + private AccessValidator accessValidator; | ||
64 | + | ||
65 | + @Value("${server.rest.server_side_rpc.min_timeout:5000}") | ||
66 | + protected long minTimeout; | ||
67 | + | ||
68 | + @Value("${server.rest.server_side_rpc.default_timeout:10000}") | ||
69 | + protected long defaultTimeout; | ||
70 | + | ||
71 | + protected DeferredResult<ResponseEntity> handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody, HttpStatus timeoutStatus, HttpStatus noActiveConnectionStatus) throws ThingsboardException { | ||
72 | + try { | ||
73 | + JsonNode rpcRequestBody = JacksonUtil.toJsonNode(requestBody); | ||
74 | + ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), JacksonUtil.toString(rpcRequestBody.get("params"))); | ||
75 | + SecurityUser currentUser = getCurrentUser(); | ||
76 | + TenantId tenantId = currentUser.getTenantId(); | ||
77 | + final DeferredResult<ResponseEntity> response = new DeferredResult<>(); | ||
78 | + long timeout = rpcRequestBody.has("timeout") ? rpcRequestBody.get("timeout").asLong() : defaultTimeout; | ||
79 | + long expTime = System.currentTimeMillis() + Math.max(minTimeout, timeout); | ||
80 | + UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID(); | ||
81 | + boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean(); | ||
82 | + String additionalInfo = JacksonUtil.toString(rpcRequestBody.get(DataConstants.ADDITIONAL_INFO)); | ||
83 | + accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<>() { | ||
84 | + @Override | ||
85 | + public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) { | ||
86 | + ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID, | ||
87 | + tenantId, | ||
88 | + deviceId, | ||
89 | + oneWay, | ||
90 | + expTime, | ||
91 | + body, | ||
92 | + persisted, | ||
93 | + additionalInfo | ||
94 | + ); | ||
95 | + deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse, timeoutStatus, noActiveConnectionStatus), currentUser); | ||
96 | + } | ||
97 | + | ||
98 | + @Override | ||
99 | + public void onFailure(Throwable e) { | ||
100 | + ResponseEntity entity; | ||
101 | + if (e instanceof ToErrorResponseEntity) { | ||
102 | + entity = ((ToErrorResponseEntity) e).toErrorResponseEntity(); | ||
103 | + } else { | ||
104 | + entity = new ResponseEntity(HttpStatus.UNAUTHORIZED); | ||
105 | + } | ||
106 | + logRpcCall(currentUser, deviceId, body, oneWay, Optional.empty(), e); | ||
107 | + response.setResult(entity); | ||
108 | + } | ||
109 | + })); | ||
110 | + return response; | ||
111 | + } catch (IllegalArgumentException ioe) { | ||
112 | + throw new ThingsboardException("Invalid request body", ioe, ThingsboardErrorCode.BAD_REQUEST_PARAMS); | ||
113 | + } | ||
114 | + } | ||
115 | + | ||
116 | + public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response, HttpStatus timeoutStatus, HttpStatus noActiveConnectionStatus) { | ||
117 | + Optional<RpcError> rpcError = response.getError(); | ||
118 | + DeferredResult<ResponseEntity> responseWriter = rpcRequest.getResponseWriter(); | ||
119 | + if (rpcError.isPresent()) { | ||
120 | + logRpcCall(rpcRequest, rpcError, null); | ||
121 | + RpcError error = rpcError.get(); | ||
122 | + switch (error) { | ||
123 | + case TIMEOUT: | ||
124 | + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); | ||
125 | + break; | ||
126 | + case NO_ACTIVE_CONNECTION: | ||
127 | + responseWriter.setResult(new ResponseEntity<>(noActiveConnectionStatus)); | ||
128 | + break; | ||
129 | + default: | ||
130 | + responseWriter.setResult(new ResponseEntity<>(timeoutStatus)); | ||
131 | + break; | ||
132 | + } | ||
133 | + } else { | ||
134 | + Optional<String> responseData = response.getResponse(); | ||
135 | + if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) { | ||
136 | + String data = responseData.get(); | ||
137 | + try { | ||
138 | + logRpcCall(rpcRequest, rpcError, null); | ||
139 | + responseWriter.setResult(new ResponseEntity<>(JacksonUtil.toJsonNode(data), HttpStatus.OK)); | ||
140 | + } catch (IllegalArgumentException e) { | ||
141 | + log.debug("Failed to decode device response: {}", data, e); | ||
142 | + logRpcCall(rpcRequest, rpcError, e); | ||
143 | + responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE)); | ||
144 | + } | ||
145 | + } else { | ||
146 | + logRpcCall(rpcRequest, rpcError, null); | ||
147 | + responseWriter.setResult(new ResponseEntity<>(HttpStatus.OK)); | ||
148 | + } | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + private void logRpcCall(LocalRequestMetaData rpcRequest, Optional<RpcError> rpcError, Throwable e) { | ||
153 | + logRpcCall(rpcRequest.getUser(), rpcRequest.getRequest().getDeviceId(), rpcRequest.getRequest().getBody(), rpcRequest.getRequest().isOneway(), rpcError, null); | ||
154 | + } | ||
155 | + | ||
156 | + | ||
157 | + private void logRpcCall(SecurityUser user, EntityId entityId, ToDeviceRpcRequestBody body, boolean oneWay, Optional<RpcError> rpcError, Throwable e) { | ||
158 | + String rpcErrorStr = ""; | ||
159 | + if (rpcError.isPresent()) { | ||
160 | + rpcErrorStr = "RPC Error: " + rpcError.get().name(); | ||
161 | + } | ||
162 | + String method = body.getMethod(); | ||
163 | + String params = body.getParams(); | ||
164 | + | ||
165 | + auditLogService.logEntityAction( | ||
166 | + user.getTenantId(), | ||
167 | + user.getCustomerId(), | ||
168 | + user.getId(), | ||
169 | + user.getName(), | ||
170 | + (UUIDBased & EntityId) entityId, | ||
171 | + null, | ||
172 | + ActionType.RPC_CALL, | ||
173 | + BaseController.toException(e), | ||
174 | + rpcErrorStr, | ||
175 | + oneWay, | ||
176 | + method, | ||
177 | + params); | ||
178 | + } | ||
179 | + | ||
180 | + | ||
181 | +} |
@@ -26,12 +26,12 @@ import org.springframework.web.bind.annotation.ResponseBody; | @@ -26,12 +26,12 @@ import org.springframework.web.bind.annotation.ResponseBody; | ||
26 | import org.springframework.web.bind.annotation.RestController; | 26 | import org.springframework.web.bind.annotation.RestController; |
27 | import org.thingsboard.rule.engine.api.MailService; | 27 | import org.thingsboard.rule.engine.api.MailService; |
28 | import org.thingsboard.rule.engine.api.SmsService; | 28 | import org.thingsboard.rule.engine.api.SmsService; |
29 | -import org.thingsboard.server.common.data.sms.config.TestSmsRequest; | ||
30 | import org.thingsboard.server.common.data.AdminSettings; | 29 | import org.thingsboard.server.common.data.AdminSettings; |
31 | import org.thingsboard.server.common.data.UpdateMessage; | 30 | import org.thingsboard.server.common.data.UpdateMessage; |
32 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 31 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
33 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
34 | import org.thingsboard.server.common.data.security.model.SecuritySettings; | 33 | import org.thingsboard.server.common.data.security.model.SecuritySettings; |
34 | +import org.thingsboard.server.common.data.sms.config.TestSmsRequest; | ||
35 | import org.thingsboard.server.dao.settings.AdminSettingsService; | 35 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
36 | import org.thingsboard.server.queue.util.TbCoreComponent; | 36 | import org.thingsboard.server.queue.util.TbCoreComponent; |
37 | import org.thingsboard.server.service.security.permission.Operation; | 37 | import org.thingsboard.server.service.security.permission.Operation; |
@@ -67,7 +67,7 @@ public class AdminController extends BaseController { | @@ -67,7 +67,7 @@ public class AdminController extends BaseController { | ||
67 | accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); | 67 | accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); |
68 | AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key)); | 68 | AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key)); |
69 | if (adminSettings.getKey().equals("mail")) { | 69 | if (adminSettings.getKey().equals("mail")) { |
70 | - ((ObjectNode) adminSettings.getJsonValue()).put("password", ""); | 70 | + ((ObjectNode) adminSettings.getJsonValue()).remove("password"); |
71 | } | 71 | } |
72 | return adminSettings; | 72 | return adminSettings; |
73 | } catch (Exception e) { | 73 | } catch (Exception e) { |
@@ -84,7 +84,7 @@ public class AdminController extends BaseController { | @@ -84,7 +84,7 @@ public class AdminController extends BaseController { | ||
84 | adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings)); | 84 | adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings)); |
85 | if (adminSettings.getKey().equals("mail")) { | 85 | if (adminSettings.getKey().equals("mail")) { |
86 | mailService.updateMailConfiguration(); | 86 | mailService.updateMailConfiguration(); |
87 | - ((ObjectNode) adminSettings.getJsonValue()).put("password", ""); | 87 | + ((ObjectNode) adminSettings.getJsonValue()).remove("password"); |
88 | } else if (adminSettings.getKey().equals("sms")) { | 88 | } else if (adminSettings.getKey().equals("sms")) { |
89 | smsService.updateSmsConfiguration(); | 89 | smsService.updateSmsConfiguration(); |
90 | } | 90 | } |
@@ -126,6 +126,10 @@ public class AdminController extends BaseController { | @@ -126,6 +126,10 @@ public class AdminController extends BaseController { | ||
126 | accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); | 126 | accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); |
127 | adminSettings = checkNotNull(adminSettings); | 127 | adminSettings = checkNotNull(adminSettings); |
128 | if (adminSettings.getKey().equals("mail")) { | 128 | if (adminSettings.getKey().equals("mail")) { |
129 | + if(!adminSettings.getJsonValue().has("password")) { | ||
130 | + AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail")); | ||
131 | + ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); | ||
132 | + } | ||
129 | String email = getCurrentUser().getEmail(); | 133 | String email = getCurrentUser().getEmail(); |
130 | mailService.sendTestMail(adminSettings.getJsonValue(), email); | 134 | mailService.sendTestMail(adminSettings.getJsonValue(), email); |
131 | } | 135 | } |
@@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; | @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType; | ||
38 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | 38 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
39 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 39 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
40 | import org.thingsboard.server.common.data.id.AlarmId; | 40 | import org.thingsboard.server.common.data.id.AlarmId; |
41 | +import org.thingsboard.server.common.data.id.EdgeId; | ||
41 | import org.thingsboard.server.common.data.id.EntityId; | 42 | import org.thingsboard.server.common.data.id.EntityId; |
42 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 43 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
43 | import org.thingsboard.server.common.data.page.PageData; | 44 | import org.thingsboard.server.common.data.page.PageData; |
@@ -46,6 +47,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -46,6 +47,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
46 | import org.thingsboard.server.service.security.permission.Operation; | 47 | import org.thingsboard.server.service.security.permission.Operation; |
47 | import org.thingsboard.server.service.security.permission.Resource; | 48 | import org.thingsboard.server.service.security.permission.Resource; |
48 | 49 | ||
50 | +import java.util.List; | ||
51 | + | ||
49 | @RestController | 52 | @RestController |
50 | @TbCoreComponent | 53 | @TbCoreComponent |
51 | @RequestMapping("/api") | 54 | @RequestMapping("/api") |
@@ -112,10 +115,13 @@ public class AlarmController extends BaseController { | @@ -112,10 +115,13 @@ public class AlarmController extends BaseController { | ||
112 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); | 115 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
113 | Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); | 116 | Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); |
114 | 117 | ||
118 | + List<EdgeId> relatedEdgeIds = findRelatedEdgeIds(getTenantId(), alarm.getOriginator()); | ||
119 | + | ||
115 | logEntityAction(alarm.getOriginator(), alarm, | 120 | logEntityAction(alarm.getOriginator(), alarm, |
116 | getCurrentUser().getCustomerId(), | 121 | getCurrentUser().getCustomerId(), |
117 | ActionType.ALARM_DELETE, null); | 122 | ActionType.ALARM_DELETE, null); |
118 | - sendEntityNotificationMsg(getTenantId(), alarmId, EdgeEventActionType.DELETED); | 123 | + |
124 | + sendAlarmDeleteNotificationMsg(getTenantId(), alarmId, relatedEdgeIds, alarm); | ||
119 | 125 | ||
120 | return alarmService.deleteAlarm(getTenantId(), alarmId); | 126 | return alarmService.deleteAlarm(getTenantId(), alarmId); |
121 | } catch (Exception e) { | 127 | } catch (Exception e) { |
@@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.DashboardInfo; | @@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.DashboardInfo; | ||
33 | import org.thingsboard.server.common.data.Device; | 33 | import org.thingsboard.server.common.data.Device; |
34 | import org.thingsboard.server.common.data.DeviceInfo; | 34 | import org.thingsboard.server.common.data.DeviceInfo; |
35 | import org.thingsboard.server.common.data.DeviceProfile; | 35 | import org.thingsboard.server.common.data.DeviceProfile; |
36 | -import org.thingsboard.server.common.data.EdgeUtils; | ||
37 | import org.thingsboard.server.common.data.EntityType; | 36 | import org.thingsboard.server.common.data.EntityType; |
38 | import org.thingsboard.server.common.data.EntityView; | 37 | import org.thingsboard.server.common.data.EntityView; |
39 | import org.thingsboard.server.common.data.EntityViewInfo; | 38 | import org.thingsboard.server.common.data.EntityViewInfo; |
@@ -118,7 +117,6 @@ import org.thingsboard.server.dao.user.UserService; | @@ -118,7 +117,6 @@ import org.thingsboard.server.dao.user.UserService; | ||
118 | import org.thingsboard.server.dao.widget.WidgetTypeService; | 117 | import org.thingsboard.server.dao.widget.WidgetTypeService; |
119 | import org.thingsboard.server.dao.widget.WidgetsBundleService; | 118 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
120 | import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; | 119 | import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; |
121 | -import org.thingsboard.server.gen.transport.TransportProtos; | ||
122 | import org.thingsboard.server.queue.discovery.PartitionService; | 120 | import org.thingsboard.server.queue.discovery.PartitionService; |
123 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 121 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
124 | import org.thingsboard.server.queue.util.TbCoreComponent; | 122 | import org.thingsboard.server.queue.util.TbCoreComponent; |
@@ -129,7 +127,7 @@ import org.thingsboard.server.service.edge.rpc.EdgeRpcService; | @@ -129,7 +127,7 @@ import org.thingsboard.server.service.edge.rpc.EdgeRpcService; | ||
129 | import org.thingsboard.server.service.lwm2m.LwM2MServerSecurityInfoRepository; | 127 | import org.thingsboard.server.service.lwm2m.LwM2MServerSecurityInfoRepository; |
130 | import org.thingsboard.server.service.ota.OtaPackageStateService; | 128 | import org.thingsboard.server.service.ota.OtaPackageStateService; |
131 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 129 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
132 | -import org.thingsboard.server.service.queue.TbClusterService; | 130 | +import org.thingsboard.server.cluster.TbClusterService; |
133 | import org.thingsboard.server.service.resource.TbResourceService; | 131 | import org.thingsboard.server.service.resource.TbResourceService; |
134 | import org.thingsboard.server.service.security.model.SecurityUser; | 132 | import org.thingsboard.server.service.security.model.SecurityUser; |
135 | import org.thingsboard.server.service.security.permission.AccessControlService; | 133 | import org.thingsboard.server.service.security.permission.AccessControlService; |
@@ -846,13 +844,25 @@ public abstract class BaseController { | @@ -846,13 +844,25 @@ public abstract class BaseController { | ||
846 | } | 844 | } |
847 | 845 | ||
848 | protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds) { | 846 | protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds) { |
847 | + sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); | ||
848 | + } | ||
849 | + | ||
850 | + protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds, String body) { | ||
849 | if (edgeIds != null && !edgeIds.isEmpty()) { | 851 | if (edgeIds != null && !edgeIds.isEmpty()) { |
850 | for (EdgeId edgeId : edgeIds) { | 852 | for (EdgeId edgeId : edgeIds) { |
851 | - sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, null, EdgeEventActionType.DELETED); | 853 | + sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, null, EdgeEventActionType.DELETED); |
852 | } | 854 | } |
853 | } | 855 | } |
854 | } | 856 | } |
855 | 857 | ||
858 | + protected void sendAlarmDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds, Alarm alarm) { | ||
859 | + try { | ||
860 | + sendDeleteNotificationMsg(tenantId, entityId, edgeIds, json.writeValueAsString(alarm)); | ||
861 | + } catch (Exception e) { | ||
862 | + log.warn("Failed to push delete alarm msg to core: {}", alarm, e); | ||
863 | + } | ||
864 | + } | ||
865 | + | ||
856 | protected void sendEntityAssignToCustomerNotificationMsg(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { | 866 | protected void sendEntityAssignToCustomerNotificationMsg(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { |
857 | try { | 867 | try { |
858 | sendNotificationMsgToEdgeService(tenantId, null, entityId, json.writeValueAsString(customerId), null, action); | 868 | sendNotificationMsgToEdgeService(tenantId, null, entityId, json.writeValueAsString(customerId), null, action); |
@@ -870,42 +880,7 @@ public abstract class BaseController { | @@ -870,42 +880,7 @@ public abstract class BaseController { | ||
870 | } | 880 | } |
871 | 881 | ||
872 | private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { | 882 | private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { |
873 | - if (!edgesEnabled) { | ||
874 | - return; | ||
875 | - } | ||
876 | - if (type == null) { | ||
877 | - if (entityId != null) { | ||
878 | - type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); | ||
879 | - } else { | ||
880 | - log.trace("[{}] entity id and type are null. Ignoring this notification", tenantId); | ||
881 | - return; | ||
882 | - } | ||
883 | - if (type == null) { | ||
884 | - log.trace("[{}] edge event type is null. Ignoring this notification [{}]", tenantId, entityId); | ||
885 | - return; | ||
886 | - } | ||
887 | - } | ||
888 | - TransportProtos.EdgeNotificationMsgProto.Builder builder = TransportProtos.EdgeNotificationMsgProto.newBuilder(); | ||
889 | - builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); | ||
890 | - builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); | ||
891 | - builder.setType(type.name()); | ||
892 | - builder.setAction(action.name()); | ||
893 | - if (entityId != null) { | ||
894 | - builder.setEntityIdMSB(entityId.getId().getMostSignificantBits()); | ||
895 | - builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits()); | ||
896 | - builder.setEntityType(entityId.getEntityType().name()); | ||
897 | - } | ||
898 | - if (edgeId != null) { | ||
899 | - builder.setEdgeIdMSB(edgeId.getId().getMostSignificantBits()); | ||
900 | - builder.setEdgeIdLSB(edgeId.getId().getLeastSignificantBits()); | ||
901 | - } | ||
902 | - if (body != null) { | ||
903 | - builder.setBody(body); | ||
904 | - } | ||
905 | - TransportProtos.EdgeNotificationMsgProto msg = builder.build(); | ||
906 | - log.trace("[{}] sending notification to edge service {}", tenantId.getId(), msg); | ||
907 | - tbClusterService.pushMsgToCore(tenantId, entityId != null ? entityId : tenantId, | ||
908 | - TransportProtos.ToCoreMsg.newBuilder().setEdgeNotificationMsg(msg).build(), null); | 883 | + tbClusterService.sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, type, action); |
909 | } | 884 | } |
910 | 885 | ||
911 | protected List<EdgeId> findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { | 886 | protected List<EdgeId> findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { |
@@ -149,7 +149,7 @@ public class CustomerController extends BaseController { | @@ -149,7 +149,7 @@ public class CustomerController extends BaseController { | ||
149 | ActionType.DELETED, null, strCustomerId); | 149 | ActionType.DELETED, null, strCustomerId); |
150 | 150 | ||
151 | sendDeleteNotificationMsg(getTenantId(), customerId, relatedEdgeIds); | 151 | sendDeleteNotificationMsg(getTenantId(), customerId, relatedEdgeIds); |
152 | - tbClusterService.onEntityStateChange(getTenantId(), customerId, ComponentLifecycleEvent.DELETED); | 152 | + tbClusterService.broadcastEntityStateChangeEvent(getTenantId(), customerId, ComponentLifecycleEvent.DELETED); |
153 | } catch (Exception e) { | 153 | } catch (Exception e) { |
154 | 154 | ||
155 | logEntityAction(emptyId(EntityType.CUSTOMER), | 155 | logEntityAction(emptyId(EntityType.CUSTOMER), |
@@ -36,7 +36,6 @@ import org.springframework.web.bind.annotation.RestController; | @@ -36,7 +36,6 @@ import org.springframework.web.bind.annotation.RestController; | ||
36 | import org.springframework.web.context.request.async.DeferredResult; | 36 | import org.springframework.web.context.request.async.DeferredResult; |
37 | import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; | 37 | import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; |
38 | import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; | 38 | import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; |
39 | -import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; | ||
40 | import org.thingsboard.server.common.data.ClaimRequest; | 39 | import org.thingsboard.server.common.data.ClaimRequest; |
41 | import org.thingsboard.server.common.data.Customer; | 40 | import org.thingsboard.server.common.data.Customer; |
42 | import org.thingsboard.server.common.data.DataConstants; | 41 | import org.thingsboard.server.common.data.DataConstants; |
@@ -60,7 +59,6 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; | @@ -60,7 +59,6 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; | ||
60 | import org.thingsboard.server.common.data.page.PageData; | 59 | import org.thingsboard.server.common.data.page.PageData; |
61 | import org.thingsboard.server.common.data.page.PageLink; | 60 | import org.thingsboard.server.common.data.page.PageLink; |
62 | import org.thingsboard.server.common.data.page.TimePageLink; | 61 | import org.thingsboard.server.common.data.page.TimePageLink; |
63 | -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
64 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 62 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
65 | import org.thingsboard.server.common.msg.TbMsg; | 63 | import org.thingsboard.server.common.msg.TbMsg; |
66 | import org.thingsboard.server.common.msg.TbMsgDataType; | 64 | import org.thingsboard.server.common.msg.TbMsgDataType; |
@@ -134,20 +132,16 @@ public class DeviceController extends BaseController { | @@ -134,20 +132,16 @@ public class DeviceController extends BaseController { | ||
134 | try { | 132 | try { |
135 | device.setTenantId(getCurrentUser().getTenantId()); | 133 | device.setTenantId(getCurrentUser().getTenantId()); |
136 | 134 | ||
137 | - checkEntity(device.getId(), device, Resource.DEVICE); | ||
138 | - | ||
139 | - Device oldDevice; | 135 | + Device oldDevice = null; |
140 | if (!created) { | 136 | if (!created) { |
141 | - oldDevice = deviceService.findDeviceById(getTenantId(), device.getId()); | 137 | + oldDevice = checkDeviceId(device.getId(), Operation.WRITE); |
142 | } else { | 138 | } else { |
143 | - oldDevice = null; | 139 | + checkEntity(null, device, Resource.DEVICE); |
144 | } | 140 | } |
145 | 141 | ||
146 | Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); | 142 | Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); |
147 | 143 | ||
148 | - onDeviceCreatedOrUpdated(savedDevice, !created); | ||
149 | - | ||
150 | - otaPackageStateService.update(savedDevice, oldDevice); | 144 | + onDeviceCreatedOrUpdated(savedDevice, oldDevice, !created); |
151 | 145 | ||
152 | return savedDevice; | 146 | return savedDevice; |
153 | } catch (Exception e) { | 147 | } catch (Exception e) { |
@@ -158,29 +152,16 @@ public class DeviceController extends BaseController { | @@ -158,29 +152,16 @@ public class DeviceController extends BaseController { | ||
158 | 152 | ||
159 | } | 153 | } |
160 | 154 | ||
161 | - private void onDeviceCreatedOrUpdated(Device device, boolean updated) { | ||
162 | - tbClusterService.onDeviceChange(device, null); | ||
163 | - tbClusterService.pushMsgToCore(new DeviceNameOrTypeUpdateMsg(device.getTenantId(), | ||
164 | - device.getId(), device.getName(), device.getType()), null); | ||
165 | - tbClusterService.onEntityStateChange(device.getTenantId(), device.getId(), updated ? ComponentLifecycleEvent.UPDATED : ComponentLifecycleEvent.CREATED); | ||
166 | - | ||
167 | - if (updated) { | ||
168 | - sendEntityNotificationMsg(device.getTenantId(), device.getId(), EdgeEventActionType.UPDATED); | ||
169 | - } | 155 | + private void onDeviceCreatedOrUpdated(Device savedDevice, Device oldDevice, boolean updated) { |
156 | + tbClusterService.onDeviceUpdated(savedDevice, oldDevice); | ||
170 | 157 | ||
171 | try { | 158 | try { |
172 | - logEntityAction(device.getId(), device, | ||
173 | - device.getCustomerId(), | 159 | + logEntityAction(savedDevice.getId(), savedDevice, |
160 | + savedDevice.getCustomerId(), | ||
174 | updated ? ActionType.UPDATED : ActionType.ADDED, null); | 161 | updated ? ActionType.UPDATED : ActionType.ADDED, null); |
175 | } catch (ThingsboardException e) { | 162 | } catch (ThingsboardException e) { |
176 | log.error("Failed to log entity action", e); | 163 | log.error("Failed to log entity action", e); |
177 | } | 164 | } |
178 | - | ||
179 | - if (updated) { | ||
180 | - deviceStateService.onDeviceUpdated(device); | ||
181 | - } else { | ||
182 | - deviceStateService.onDeviceAdded(device); | ||
183 | - } | ||
184 | } | 165 | } |
185 | 166 | ||
186 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 167 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
@@ -197,15 +178,12 @@ public class DeviceController extends BaseController { | @@ -197,15 +178,12 @@ public class DeviceController extends BaseController { | ||
197 | deviceService.deleteDevice(getCurrentUser().getTenantId(), deviceId); | 178 | deviceService.deleteDevice(getCurrentUser().getTenantId(), deviceId); |
198 | 179 | ||
199 | tbClusterService.onDeviceDeleted(device, null); | 180 | tbClusterService.onDeviceDeleted(device, null); |
200 | - tbClusterService.onEntityStateChange(device.getTenantId(), deviceId, ComponentLifecycleEvent.DELETED); | ||
201 | 181 | ||
202 | logEntityAction(deviceId, device, | 182 | logEntityAction(deviceId, device, |
203 | device.getCustomerId(), | 183 | device.getCustomerId(), |
204 | ActionType.DELETED, null, strDeviceId); | 184 | ActionType.DELETED, null, strDeviceId); |
205 | 185 | ||
206 | sendDeleteNotificationMsg(getTenantId(), deviceId, relatedEdgeIds); | 186 | sendDeleteNotificationMsg(getTenantId(), deviceId, relatedEdgeIds); |
207 | - | ||
208 | - deviceStateService.onDeviceDeleted(device); | ||
209 | } catch (Exception e) { | 187 | } catch (Exception e) { |
210 | logEntityAction(emptyId(EntityType.DEVICE), | 188 | logEntityAction(emptyId(EntityType.DEVICE), |
211 | null, | 189 | null, |
@@ -819,8 +797,7 @@ public class DeviceController extends BaseController { | @@ -819,8 +797,7 @@ public class DeviceController extends BaseController { | ||
819 | @PostMapping("/device/bulk_import") | 797 | @PostMapping("/device/bulk_import") |
820 | public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception { | 798 | public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception { |
821 | return deviceBulkImportService.processBulkImport(request, getCurrentUser(), importedDeviceInfo -> { | 799 | return deviceBulkImportService.processBulkImport(request, getCurrentUser(), importedDeviceInfo -> { |
822 | - onDeviceCreatedOrUpdated(importedDeviceInfo.getEntity(), importedDeviceInfo.isUpdated()); | ||
823 | - otaPackageStateService.update(importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity()); | 800 | + onDeviceCreatedOrUpdated(importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), importedDeviceInfo.isUpdated()); |
824 | }); | 801 | }); |
825 | } | 802 | } |
826 | 803 |
@@ -161,7 +161,7 @@ public class DeviceProfileController extends BaseController { | @@ -161,7 +161,7 @@ public class DeviceProfileController extends BaseController { | ||
161 | DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); | 161 | DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); |
162 | 162 | ||
163 | tbClusterService.onDeviceProfileChange(savedDeviceProfile, null); | 163 | tbClusterService.onDeviceProfileChange(savedDeviceProfile, null); |
164 | - tbClusterService.onEntityStateChange(deviceProfile.getTenantId(), savedDeviceProfile.getId(), | 164 | + tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), savedDeviceProfile.getId(), |
165 | created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | 165 | created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); |
166 | 166 | ||
167 | logEntityAction(savedDeviceProfile.getId(), savedDeviceProfile, | 167 | logEntityAction(savedDeviceProfile.getId(), savedDeviceProfile, |
@@ -191,7 +191,7 @@ public class DeviceProfileController extends BaseController { | @@ -191,7 +191,7 @@ public class DeviceProfileController extends BaseController { | ||
191 | deviceProfileService.deleteDeviceProfile(getTenantId(), deviceProfileId); | 191 | deviceProfileService.deleteDeviceProfile(getTenantId(), deviceProfileId); |
192 | 192 | ||
193 | tbClusterService.onDeviceProfileDelete(deviceProfile, null); | 193 | tbClusterService.onDeviceProfileDelete(deviceProfile, null); |
194 | - tbClusterService.onEntityStateChange(deviceProfile.getTenantId(), deviceProfile.getId(), ComponentLifecycleEvent.DELETED); | 194 | + tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), deviceProfile.getId(), ComponentLifecycleEvent.DELETED); |
195 | 195 | ||
196 | logEntityAction(deviceProfileId, deviceProfile, | 196 | logEntityAction(deviceProfileId, deviceProfile, |
197 | null, | 197 | null, |
@@ -153,7 +153,7 @@ public class EdgeController extends BaseController { | @@ -153,7 +153,7 @@ public class EdgeController extends BaseController { | ||
153 | edgeService.assignDefaultRuleChainsToEdge(tenantId, edge.getId()); | 153 | edgeService.assignDefaultRuleChainsToEdge(tenantId, edge.getId()); |
154 | } | 154 | } |
155 | 155 | ||
156 | - tbClusterService.onEntityStateChange(edge.getTenantId(), edge.getId(), | 156 | + tbClusterService.broadcastEntityStateChangeEvent(edge.getTenantId(), edge.getId(), |
157 | updated ? ComponentLifecycleEvent.UPDATED : ComponentLifecycleEvent.CREATED); | 157 | updated ? ComponentLifecycleEvent.UPDATED : ComponentLifecycleEvent.CREATED); |
158 | 158 | ||
159 | logEntityAction(edge.getId(), edge, null, updated ? ActionType.UPDATED : ActionType.ADDED, null); | 159 | logEntityAction(edge.getId(), edge, null, updated ? ActionType.UPDATED : ActionType.ADDED, null); |
@@ -169,7 +169,7 @@ public class EdgeController extends BaseController { | @@ -169,7 +169,7 @@ public class EdgeController extends BaseController { | ||
169 | Edge edge = checkEdgeId(edgeId, Operation.DELETE); | 169 | Edge edge = checkEdgeId(edgeId, Operation.DELETE); |
170 | edgeService.deleteEdge(getTenantId(), edgeId); | 170 | edgeService.deleteEdge(getTenantId(), edgeId); |
171 | 171 | ||
172 | - tbClusterService.onEntityStateChange(getTenantId(), edgeId, | 172 | + tbClusterService.broadcastEntityStateChangeEvent(getTenantId(), edgeId, |
173 | ComponentLifecycleEvent.DELETED); | 173 | ComponentLifecycleEvent.DELETED); |
174 | 174 | ||
175 | logEntityAction(edgeId, edge, | 175 | logEntityAction(edgeId, edge, |
@@ -220,7 +220,7 @@ public class EdgeController extends BaseController { | @@ -220,7 +220,7 @@ public class EdgeController extends BaseController { | ||
220 | 220 | ||
221 | Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, customerId)); | 221 | Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, customerId)); |
222 | 222 | ||
223 | - tbClusterService.onEntityStateChange(getTenantId(), edgeId, | 223 | + tbClusterService.broadcastEntityStateChangeEvent(getTenantId(), edgeId, |
224 | ComponentLifecycleEvent.UPDATED); | 224 | ComponentLifecycleEvent.UPDATED); |
225 | 225 | ||
226 | logEntityAction(edgeId, savedEdge, | 226 | logEntityAction(edgeId, savedEdge, |
@@ -254,7 +254,7 @@ public class EdgeController extends BaseController { | @@ -254,7 +254,7 @@ public class EdgeController extends BaseController { | ||
254 | 254 | ||
255 | Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(getCurrentUser().getTenantId(), edgeId)); | 255 | Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(getCurrentUser().getTenantId(), edgeId)); |
256 | 256 | ||
257 | - tbClusterService.onEntityStateChange(getTenantId(), edgeId, | 257 | + tbClusterService.broadcastEntityStateChangeEvent(getTenantId(), edgeId, |
258 | ComponentLifecycleEvent.UPDATED); | 258 | ComponentLifecycleEvent.UPDATED); |
259 | 259 | ||
260 | logEntityAction(edgeId, edge, | 260 | logEntityAction(edgeId, edge, |
@@ -284,7 +284,7 @@ public class EdgeController extends BaseController { | @@ -284,7 +284,7 @@ public class EdgeController extends BaseController { | ||
284 | Customer publicCustomer = customerService.findOrCreatePublicCustomer(edge.getTenantId()); | 284 | Customer publicCustomer = customerService.findOrCreatePublicCustomer(edge.getTenantId()); |
285 | Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, publicCustomer.getId())); | 285 | Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, publicCustomer.getId())); |
286 | 286 | ||
287 | - tbClusterService.onEntityStateChange(getTenantId(), edgeId, | 287 | + tbClusterService.broadcastEntityStateChangeEvent(getTenantId(), edgeId, |
288 | ComponentLifecycleEvent.UPDATED); | 288 | ComponentLifecycleEvent.UPDATED); |
289 | 289 | ||
290 | logEntityAction(edgeId, savedEdge, | 290 | logEntityAction(edgeId, savedEdge, |
@@ -376,7 +376,7 @@ public class EdgeController extends BaseController { | @@ -376,7 +376,7 @@ public class EdgeController extends BaseController { | ||
376 | 376 | ||
377 | Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); | 377 | Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); |
378 | 378 | ||
379 | - tbClusterService.onEntityStateChange(updatedEdge.getTenantId(), updatedEdge.getId(), ComponentLifecycleEvent.UPDATED); | 379 | + tbClusterService.broadcastEntityStateChangeEvent(updatedEdge.getTenantId(), updatedEdge.getId(), ComponentLifecycleEvent.UPDATED); |
380 | 380 | ||
381 | logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null); | 381 | logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null); |
382 | 382 |
@@ -24,13 +24,11 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -24,13 +24,11 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
24 | import org.springframework.web.bind.annotation.RequestMethod; | 24 | import org.springframework.web.bind.annotation.RequestMethod; |
25 | import org.springframework.web.bind.annotation.ResponseBody; | 25 | import org.springframework.web.bind.annotation.ResponseBody; |
26 | import org.springframework.web.bind.annotation.RestController; | 26 | import org.springframework.web.bind.annotation.RestController; |
27 | -import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; | ||
28 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
29 | import org.thingsboard.server.common.data.EntityType; | 28 | import org.thingsboard.server.common.data.EntityType; |
30 | import org.thingsboard.server.common.data.audit.ActionType; | 29 | import org.thingsboard.server.common.data.audit.ActionType; |
31 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 30 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
32 | import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig; | 31 | import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig; |
33 | -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
34 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 32 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
35 | import org.thingsboard.server.queue.util.TbCoreComponent; | 33 | import org.thingsboard.server.queue.util.TbCoreComponent; |
36 | import org.thingsboard.server.service.security.permission.Resource; | 34 | import org.thingsboard.server.service.security.permission.Resource; |
@@ -66,22 +64,11 @@ public class Lwm2mController extends BaseController { | @@ -66,22 +64,11 @@ public class Lwm2mController extends BaseController { | ||
66 | checkEntity(device.getId(), device, Resource.DEVICE); | 64 | checkEntity(device.getId(), device, Resource.DEVICE); |
67 | Device savedDevice = deviceService.saveDeviceWithCredentials(device, credentials); | 65 | Device savedDevice = deviceService.saveDeviceWithCredentials(device, credentials); |
68 | checkNotNull(savedDevice); | 66 | checkNotNull(savedDevice); |
69 | - | ||
70 | - tbClusterService.onDeviceChange(savedDevice, null); | ||
71 | - tbClusterService.pushMsgToCore(new DeviceNameOrTypeUpdateMsg(savedDevice.getTenantId(), | ||
72 | - savedDevice.getId(), savedDevice.getName(), savedDevice.getType()), null); | ||
73 | - tbClusterService.onEntityStateChange(savedDevice.getTenantId(), savedDevice.getId(), | ||
74 | - device.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | ||
75 | - | 67 | + tbClusterService.onDeviceUpdated(savedDevice, device); |
76 | logEntityAction(savedDevice.getId(), savedDevice, | 68 | logEntityAction(savedDevice.getId(), savedDevice, |
77 | savedDevice.getCustomerId(), | 69 | savedDevice.getCustomerId(), |
78 | device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); | 70 | device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); |
79 | 71 | ||
80 | - if (device.getId() == null) { | ||
81 | - deviceStateService.onDeviceAdded(savedDevice); | ||
82 | - } else { | ||
83 | - deviceStateService.onDeviceUpdated(savedDevice); | ||
84 | - } | ||
85 | return savedDevice; | 72 | return savedDevice; |
86 | } catch (Exception e) { | 73 | } catch (Exception e) { |
87 | logEntityAction(emptyId(EntityType.DEVICE), device, | 74 | logEntityAction(emptyId(EntityType.DEVICE), device, |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.springframework.http.HttpStatus; | ||
20 | +import org.springframework.http.ResponseEntity; | ||
21 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
22 | +import org.springframework.web.bind.annotation.PathVariable; | ||
23 | +import org.springframework.web.bind.annotation.RequestBody; | ||
24 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
25 | +import org.springframework.web.bind.annotation.RequestMethod; | ||
26 | +import org.springframework.web.bind.annotation.ResponseBody; | ||
27 | +import org.springframework.web.bind.annotation.RestController; | ||
28 | +import org.springframework.web.context.request.async.DeferredResult; | ||
29 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | ||
30 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
31 | +import org.thingsboard.server.queue.util.TbCoreComponent; | ||
32 | + | ||
33 | +import java.util.UUID; | ||
34 | + | ||
35 | +@RestController | ||
36 | +@TbCoreComponent | ||
37 | +@RequestMapping(TbUrlConstants.RPC_V1_URL_PREFIX) | ||
38 | +@Slf4j | ||
39 | +public class RpcV1Controller extends AbstractRpcController { | ||
40 | + | ||
41 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | ||
42 | + @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) | ||
43 | + @ResponseBody | ||
44 | + public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | ||
45 | + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); | ||
46 | + } | ||
47 | + | ||
48 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | ||
49 | + @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) | ||
50 | + @ResponseBody | ||
51 | + public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | ||
52 | + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); | ||
53 | + } | ||
54 | + | ||
55 | +} |
application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java
renamed from
application/src/main/java/org/thingsboard/server/controller/RpcController.java
@@ -15,16 +15,10 @@ | @@ -15,16 +15,10 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | -import com.fasterxml.jackson.databind.JsonNode; | ||
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | -import com.google.common.util.concurrent.FutureCallback; | ||
21 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
22 | -import org.springframework.beans.factory.annotation.Autowired; | ||
23 | -import org.springframework.beans.factory.annotation.Value; | ||
24 | import org.springframework.http.HttpStatus; | 19 | import org.springframework.http.HttpStatus; |
25 | import org.springframework.http.ResponseEntity; | 20 | import org.springframework.http.ResponseEntity; |
26 | import org.springframework.security.access.prepost.PreAuthorize; | 21 | import org.springframework.security.access.prepost.PreAuthorize; |
27 | -import org.springframework.util.StringUtils; | ||
28 | import org.springframework.web.bind.annotation.PathVariable; | 22 | import org.springframework.web.bind.annotation.PathVariable; |
29 | import org.springframework.web.bind.annotation.RequestBody; | 23 | import org.springframework.web.bind.annotation.RequestBody; |
30 | import org.springframework.web.bind.annotation.RequestMapping; | 24 | import org.springframework.web.bind.annotation.RequestMapping; |
@@ -33,71 +27,43 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -33,71 +27,43 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
33 | import org.springframework.web.bind.annotation.ResponseBody; | 27 | import org.springframework.web.bind.annotation.ResponseBody; |
34 | import org.springframework.web.bind.annotation.RestController; | 28 | import org.springframework.web.bind.annotation.RestController; |
35 | import org.springframework.web.context.request.async.DeferredResult; | 29 | import org.springframework.web.context.request.async.DeferredResult; |
36 | -import org.thingsboard.rule.engine.api.RpcError; | ||
37 | -import org.thingsboard.server.common.data.DataConstants; | ||
38 | -import org.thingsboard.server.common.data.audit.ActionType; | ||
39 | -import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | 30 | +import org.thingsboard.common.util.JacksonUtil; |
40 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 31 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
41 | import org.thingsboard.server.common.data.id.DeviceId; | 32 | import org.thingsboard.server.common.data.id.DeviceId; |
42 | -import org.thingsboard.server.common.data.id.EntityId; | ||
43 | import org.thingsboard.server.common.data.id.RpcId; | 33 | import org.thingsboard.server.common.data.id.RpcId; |
44 | import org.thingsboard.server.common.data.id.TenantId; | 34 | import org.thingsboard.server.common.data.id.TenantId; |
45 | -import org.thingsboard.server.common.data.id.UUIDBased; | ||
46 | import org.thingsboard.server.common.data.page.PageData; | 35 | import org.thingsboard.server.common.data.page.PageData; |
47 | import org.thingsboard.server.common.data.page.PageLink; | 36 | import org.thingsboard.server.common.data.page.PageLink; |
48 | import org.thingsboard.server.common.data.rpc.Rpc; | 37 | import org.thingsboard.server.common.data.rpc.Rpc; |
49 | import org.thingsboard.server.common.data.rpc.RpcStatus; | 38 | import org.thingsboard.server.common.data.rpc.RpcStatus; |
50 | -import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; | ||
51 | -import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 39 | +import org.thingsboard.server.common.msg.TbMsg; |
40 | +import org.thingsboard.server.common.msg.TbMsgMetaData; | ||
52 | import org.thingsboard.server.queue.util.TbCoreComponent; | 41 | import org.thingsboard.server.queue.util.TbCoreComponent; |
53 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | ||
54 | -import org.thingsboard.server.service.rpc.LocalRequestMetaData; | ||
55 | -import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | ||
56 | -import org.thingsboard.server.service.security.AccessValidator; | ||
57 | -import org.thingsboard.server.service.security.model.SecurityUser; | 42 | +import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; |
58 | import org.thingsboard.server.service.security.permission.Operation; | 43 | import org.thingsboard.server.service.security.permission.Operation; |
59 | -import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity; | ||
60 | 44 | ||
61 | -import javax.annotation.Nullable; | ||
62 | -import java.io.IOException; | ||
63 | -import java.util.Optional; | ||
64 | import java.util.UUID; | 45 | import java.util.UUID; |
65 | 46 | ||
66 | -/** | ||
67 | - * Created by ashvayka on 22.03.18. | ||
68 | - */ | 47 | +import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED; |
48 | + | ||
69 | @RestController | 49 | @RestController |
70 | @TbCoreComponent | 50 | @TbCoreComponent |
71 | -@RequestMapping(TbUrlConstants.RPC_URL_PREFIX) | 51 | +@RequestMapping(TbUrlConstants.RPC_V2_URL_PREFIX) |
72 | @Slf4j | 52 | @Slf4j |
73 | -public class RpcController extends BaseController { | ||
74 | - | ||
75 | - protected final ObjectMapper jsonMapper = new ObjectMapper(); | ||
76 | - | ||
77 | - @Autowired | ||
78 | - private TbCoreDeviceRpcService deviceRpcService; | ||
79 | - | ||
80 | - @Autowired | ||
81 | - private AccessValidator accessValidator; | ||
82 | - | ||
83 | - @Value("${server.rest.server_side_rpc.min_timeout:5000}") | ||
84 | - private long minTimeout; | ||
85 | - | ||
86 | - @Value("${server.rest.server_side_rpc.default_timeout:10000}") | ||
87 | - private long defaultTimeout; | 53 | +public class RpcV2Controller extends AbstractRpcController { |
88 | 54 | ||
89 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | 55 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
90 | @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) | 56 | @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) |
91 | @ResponseBody | 57 | @ResponseBody |
92 | public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | 58 | public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { |
93 | - return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); | 59 | + return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); |
94 | } | 60 | } |
95 | 61 | ||
96 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | 62 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
97 | @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) | 63 | @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) |
98 | @ResponseBody | 64 | @ResponseBody |
99 | public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { | 65 | public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(@PathVariable("deviceId") String deviceIdStr, @RequestBody String requestBody) throws ThingsboardException { |
100 | - return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody); | 66 | + return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); |
101 | } | 67 | } |
102 | 68 | ||
103 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 69 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
@@ -140,118 +106,23 @@ public class RpcController extends BaseController { | @@ -140,118 +106,23 @@ public class RpcController extends BaseController { | ||
140 | public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { | 106 | public void deleteResource(@PathVariable("rpcId") String strRpc) throws ThingsboardException { |
141 | checkParameter("RpcId", strRpc); | 107 | checkParameter("RpcId", strRpc); |
142 | try { | 108 | try { |
143 | - rpcService.deleteRpc(getTenantId(), new RpcId(UUID.fromString(strRpc))); | ||
144 | - } catch (Exception e) { | ||
145 | - throw handleException(e); | ||
146 | - } | ||
147 | - } | 109 | + RpcId rpcId = new RpcId(UUID.fromString(strRpc)); |
110 | + Rpc rpc = checkRpcId(rpcId, Operation.DELETE); | ||
148 | 111 | ||
149 | - private DeferredResult<ResponseEntity> handleDeviceRPCRequest(boolean oneWay, DeviceId deviceId, String requestBody) throws ThingsboardException { | ||
150 | - try { | ||
151 | - JsonNode rpcRequestBody = jsonMapper.readTree(requestBody); | ||
152 | - ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(rpcRequestBody.get("method").asText(), jsonMapper.writeValueAsString(rpcRequestBody.get("params"))); | ||
153 | - SecurityUser currentUser = getCurrentUser(); | ||
154 | - TenantId tenantId = currentUser.getTenantId(); | ||
155 | - final DeferredResult<ResponseEntity> response = new DeferredResult<>(); | ||
156 | - long timeout = rpcRequestBody.has("timeout") ? rpcRequestBody.get("timeout").asLong() : defaultTimeout; | ||
157 | - long expTime = System.currentTimeMillis() + Math.max(minTimeout, timeout); | ||
158 | - UUID rpcRequestUUID = rpcRequestBody.has("requestUUID") ? UUID.fromString(rpcRequestBody.get("requestUUID").asText()) : UUID.randomUUID(); | ||
159 | - boolean persisted = rpcRequestBody.has(DataConstants.PERSISTENT) && rpcRequestBody.get(DataConstants.PERSISTENT).asBoolean(); | ||
160 | - accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback<DeferredResult<ResponseEntity>>() { | ||
161 | - @Override | ||
162 | - public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) { | ||
163 | - ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(rpcRequestUUID, | ||
164 | - tenantId, | ||
165 | - deviceId, | ||
166 | - oneWay, | ||
167 | - expTime, | ||
168 | - body, | ||
169 | - persisted | ||
170 | - ); | ||
171 | - deviceRpcService.processRestApiRpcRequest(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse), currentUser); | 112 | + if (rpc != null) { |
113 | + if (rpc.getStatus().equals(RpcStatus.QUEUED)) { | ||
114 | + RemoveRpcActorMsg removeMsg = new RemoveRpcActorMsg(getTenantId(), rpc.getDeviceId(), rpc.getUuidId()); | ||
115 | + log.trace("[{}] Forwarding msg {} to queue actor!", rpc.getDeviceId(), rpc); | ||
116 | + tbClusterService.pushMsgToCore(removeMsg, null); | ||
172 | } | 117 | } |
173 | 118 | ||
174 | - @Override | ||
175 | - public void onFailure(Throwable e) { | ||
176 | - ResponseEntity entity; | ||
177 | - if (e instanceof ToErrorResponseEntity) { | ||
178 | - entity = ((ToErrorResponseEntity) e).toErrorResponseEntity(); | ||
179 | - } else { | ||
180 | - entity = new ResponseEntity(HttpStatus.UNAUTHORIZED); | ||
181 | - } | ||
182 | - logRpcCall(currentUser, deviceId, body, oneWay, Optional.empty(), e); | ||
183 | - response.setResult(entity); | ||
184 | - } | ||
185 | - })); | ||
186 | - return response; | ||
187 | - } catch (IOException ioe) { | ||
188 | - throw new ThingsboardException("Invalid request body", ioe, ThingsboardErrorCode.BAD_REQUEST_PARAMS); | ||
189 | - } | ||
190 | - } | 119 | + rpcService.deleteRpc(getTenantId(), rpcId); |
191 | 120 | ||
192 | - public void reply(LocalRequestMetaData rpcRequest, FromDeviceRpcResponse response) { | ||
193 | - Optional<RpcError> rpcError = response.getError(); | ||
194 | - DeferredResult<ResponseEntity> responseWriter = rpcRequest.getResponseWriter(); | ||
195 | - if (rpcError.isPresent()) { | ||
196 | - logRpcCall(rpcRequest, rpcError, null); | ||
197 | - RpcError error = rpcError.get(); | ||
198 | - switch (error) { | ||
199 | - case TIMEOUT: | ||
200 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); | ||
201 | - break; | ||
202 | - case NO_ACTIVE_CONNECTION: | ||
203 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.CONFLICT)); | ||
204 | - break; | ||
205 | - default: | ||
206 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); | ||
207 | - break; | ||
208 | - } | ||
209 | - } else { | ||
210 | - Optional<String> responseData = response.getResponse(); | ||
211 | - if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) { | ||
212 | - String data = responseData.get(); | ||
213 | - try { | ||
214 | - logRpcCall(rpcRequest, rpcError, null); | ||
215 | - responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); | ||
216 | - } catch (IOException e) { | ||
217 | - log.debug("Failed to decode device response: {}", data, e); | ||
218 | - logRpcCall(rpcRequest, rpcError, e); | ||
219 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE)); | ||
220 | - } | ||
221 | - } else { | ||
222 | - logRpcCall(rpcRequest, rpcError, null); | ||
223 | - responseWriter.setResult(new ResponseEntity<>(HttpStatus.OK)); | 121 | + TbMsg msg = TbMsg.newMsg(RPC_DELETED, rpc.getDeviceId(), TbMsgMetaData.EMPTY, JacksonUtil.toString(rpc)); |
122 | + tbClusterService.pushMsgToRuleEngine(getTenantId(), rpc.getDeviceId(), msg, null); | ||
224 | } | 123 | } |
124 | + } catch (Exception e) { | ||
125 | + throw handleException(e); | ||
225 | } | 126 | } |
226 | } | 127 | } |
227 | - | ||
228 | - private void logRpcCall(LocalRequestMetaData rpcRequest, Optional<RpcError> rpcError, Throwable e) { | ||
229 | - logRpcCall(rpcRequest.getUser(), rpcRequest.getRequest().getDeviceId(), rpcRequest.getRequest().getBody(), rpcRequest.getRequest().isOneway(), rpcError, null); | ||
230 | - } | ||
231 | - | ||
232 | - | ||
233 | - private void logRpcCall(SecurityUser user, EntityId entityId, ToDeviceRpcRequestBody body, boolean oneWay, Optional<RpcError> rpcError, Throwable e) { | ||
234 | - String rpcErrorStr = ""; | ||
235 | - if (rpcError.isPresent()) { | ||
236 | - rpcErrorStr = "RPC Error: " + rpcError.get().name(); | ||
237 | - } | ||
238 | - String method = body.getMethod(); | ||
239 | - String params = body.getParams(); | ||
240 | - | ||
241 | - auditLogService.logEntityAction( | ||
242 | - user.getTenantId(), | ||
243 | - user.getCustomerId(), | ||
244 | - user.getId(), | ||
245 | - user.getName(), | ||
246 | - (UUIDBased & EntityId) entityId, | ||
247 | - null, | ||
248 | - ActionType.RPC_CALL, | ||
249 | - BaseController.toException(e), | ||
250 | - rpcErrorStr, | ||
251 | - oneWay, | ||
252 | - method, | ||
253 | - params); | ||
254 | - } | ||
255 | - | ||
256 | - | ||
257 | } | 128 | } |
@@ -149,7 +149,7 @@ public class RuleChainController extends BaseController { | @@ -149,7 +149,7 @@ public class RuleChainController extends BaseController { | ||
149 | RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); | 149 | RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); |
150 | 150 | ||
151 | if (RuleChainType.CORE.equals(savedRuleChain.getType())) { | 151 | if (RuleChainType.CORE.equals(savedRuleChain.getType())) { |
152 | - tbClusterService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(), | 152 | + tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), savedRuleChain.getId(), |
153 | created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | 153 | created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); |
154 | } | 154 | } |
155 | 155 | ||
@@ -183,7 +183,7 @@ public class RuleChainController extends BaseController { | @@ -183,7 +183,7 @@ public class RuleChainController extends BaseController { | ||
183 | 183 | ||
184 | RuleChain savedRuleChain = installScripts.createDefaultRuleChain(getCurrentUser().getTenantId(), request.getName()); | 184 | RuleChain savedRuleChain = installScripts.createDefaultRuleChain(getCurrentUser().getTenantId(), request.getName()); |
185 | 185 | ||
186 | - tbClusterService.onEntityStateChange(savedRuleChain.getTenantId(), savedRuleChain.getId(), ComponentLifecycleEvent.CREATED); | 186 | + tbClusterService.broadcastEntityStateChangeEvent(savedRuleChain.getTenantId(), savedRuleChain.getId(), ComponentLifecycleEvent.CREATED); |
187 | 187 | ||
188 | logEntityAction(savedRuleChain.getId(), savedRuleChain, null, ActionType.ADDED, null); | 188 | logEntityAction(savedRuleChain.getId(), savedRuleChain, null, ActionType.ADDED, null); |
189 | 189 | ||
@@ -210,7 +210,7 @@ public class RuleChainController extends BaseController { | @@ -210,7 +210,7 @@ public class RuleChainController extends BaseController { | ||
210 | if (previousRootRuleChain != null) { | 210 | if (previousRootRuleChain != null) { |
211 | previousRootRuleChain = ruleChainService.findRuleChainById(getTenantId(), previousRootRuleChain.getId()); | 211 | previousRootRuleChain = ruleChainService.findRuleChainById(getTenantId(), previousRootRuleChain.getId()); |
212 | 212 | ||
213 | - tbClusterService.onEntityStateChange(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(), | 213 | + tbClusterService.broadcastEntityStateChangeEvent(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(), |
214 | ComponentLifecycleEvent.UPDATED); | 214 | ComponentLifecycleEvent.UPDATED); |
215 | 215 | ||
216 | logEntityAction(previousRootRuleChain.getId(), previousRootRuleChain, | 216 | logEntityAction(previousRootRuleChain.getId(), previousRootRuleChain, |
@@ -218,7 +218,7 @@ public class RuleChainController extends BaseController { | @@ -218,7 +218,7 @@ public class RuleChainController extends BaseController { | ||
218 | } | 218 | } |
219 | ruleChain = ruleChainService.findRuleChainById(getTenantId(), ruleChainId); | 219 | ruleChain = ruleChainService.findRuleChainById(getTenantId(), ruleChainId); |
220 | 220 | ||
221 | - tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), | 221 | + tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), |
222 | ComponentLifecycleEvent.UPDATED); | 222 | ComponentLifecycleEvent.UPDATED); |
223 | 223 | ||
224 | logEntityAction(ruleChain.getId(), ruleChain, | 224 | logEntityAction(ruleChain.getId(), ruleChain, |
@@ -254,7 +254,7 @@ public class RuleChainController extends BaseController { | @@ -254,7 +254,7 @@ public class RuleChainController extends BaseController { | ||
254 | RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); | 254 | RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId())); |
255 | 255 | ||
256 | if (RuleChainType.CORE.equals(ruleChain.getType())) { | 256 | if (RuleChainType.CORE.equals(ruleChain.getType())) { |
257 | - tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); | 257 | + tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); |
258 | } | 258 | } |
259 | 259 | ||
260 | logEntityAction(ruleChain.getId(), ruleChain, | 260 | logEntityAction(ruleChain.getId(), ruleChain, |
@@ -323,9 +323,9 @@ public class RuleChainController extends BaseController { | @@ -323,9 +323,9 @@ public class RuleChainController extends BaseController { | ||
323 | 323 | ||
324 | if (RuleChainType.CORE.equals(ruleChain.getType())) { | 324 | if (RuleChainType.CORE.equals(ruleChain.getType())) { |
325 | referencingRuleChainIds.forEach(referencingRuleChainId -> | 325 | referencingRuleChainIds.forEach(referencingRuleChainId -> |
326 | - tbClusterService.onEntityStateChange(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED)); | 326 | + tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED)); |
327 | 327 | ||
328 | - tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED); | 328 | + tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED); |
329 | } | 329 | } |
330 | 330 | ||
331 | logEntityAction(ruleChainId, ruleChain, | 331 | logEntityAction(ruleChainId, ruleChain, |
@@ -456,7 +456,7 @@ public class RuleChainController extends BaseController { | @@ -456,7 +456,7 @@ public class RuleChainController extends BaseController { | ||
456 | List<RuleChainImportResult> importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, RuleChainType.CORE, overwrite); | 456 | List<RuleChainImportResult> importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, RuleChainType.CORE, overwrite); |
457 | if (!CollectionUtils.isEmpty(importResults)) { | 457 | if (!CollectionUtils.isEmpty(importResults)) { |
458 | for (RuleChainImportResult importResult : importResults) { | 458 | for (RuleChainImportResult importResult : importResults) { |
459 | - tbClusterService.onEntityStateChange(importResult.getTenantId(), importResult.getRuleChainId(), importResult.getLifecycleEvent()); | 459 | + tbClusterService.broadcastEntityStateChangeEvent(importResult.getTenantId(), importResult.getRuleChainId(), importResult.getLifecycleEvent()); |
460 | } | 460 | } |
461 | } | 461 | } |
462 | } catch (Exception e) { | 462 | } catch (Exception e) { |
@@ -20,5 +20,6 @@ package org.thingsboard.server.controller; | @@ -20,5 +20,6 @@ package org.thingsboard.server.controller; | ||
20 | */ | 20 | */ |
21 | public class TbUrlConstants { | 21 | public class TbUrlConstants { |
22 | public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry"; | 22 | public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry"; |
23 | - public static final String RPC_URL_PREFIX = "/api/plugins/rpc"; | 23 | + public static final String RPC_V1_URL_PREFIX = "/api/plugins/rpc"; |
24 | + public static final String RPC_V2_URL_PREFIX = "/api/rpc"; | ||
24 | } | 25 | } |
@@ -99,7 +99,7 @@ public class TenantController extends BaseController { | @@ -99,7 +99,7 @@ public class TenantController extends BaseController { | ||
99 | } | 99 | } |
100 | tenantProfileCache.evict(tenant.getId()); | 100 | tenantProfileCache.evict(tenant.getId()); |
101 | tbClusterService.onTenantChange(tenant, null); | 101 | tbClusterService.onTenantChange(tenant, null); |
102 | - tbClusterService.onEntityStateChange(tenant.getId(), tenant.getId(), | 102 | + tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), |
103 | newTenant ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | 103 | newTenant ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); |
104 | return tenant; | 104 | return tenant; |
105 | } catch (Exception e) { | 105 | } catch (Exception e) { |
@@ -118,7 +118,7 @@ public class TenantController extends BaseController { | @@ -118,7 +118,7 @@ public class TenantController extends BaseController { | ||
118 | tenantService.deleteTenant(tenantId); | 118 | tenantService.deleteTenant(tenantId); |
119 | tenantProfileCache.evict(tenantId); | 119 | tenantProfileCache.evict(tenantId); |
120 | tbClusterService.onTenantDelete(tenant, null); | 120 | tbClusterService.onTenantDelete(tenant, null); |
121 | - tbClusterService.onEntityStateChange(tenantId, tenantId, ComponentLifecycleEvent.DELETED); | 121 | + tbClusterService.broadcastEntityStateChangeEvent(tenantId, tenantId, ComponentLifecycleEvent.DELETED); |
122 | } catch (Exception e) { | 122 | } catch (Exception e) { |
123 | throw handleException(e); | 123 | throw handleException(e); |
124 | } | 124 | } |
@@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId; | @@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId; | ||
34 | import org.thingsboard.server.common.data.page.PageData; | 34 | import org.thingsboard.server.common.data.page.PageData; |
35 | import org.thingsboard.server.common.data.page.PageLink; | 35 | import org.thingsboard.server.common.data.page.PageLink; |
36 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | 36 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
37 | -import org.thingsboard.server.dao.exception.DataValidationException; | ||
38 | import org.thingsboard.server.queue.util.TbCoreComponent; | 37 | import org.thingsboard.server.queue.util.TbCoreComponent; |
39 | import org.thingsboard.server.service.security.permission.Operation; | 38 | import org.thingsboard.server.service.security.permission.Operation; |
40 | import org.thingsboard.server.service.security.permission.Resource; | 39 | import org.thingsboard.server.service.security.permission.Resource; |
@@ -98,7 +97,7 @@ public class TenantProfileController extends BaseController { | @@ -98,7 +97,7 @@ public class TenantProfileController extends BaseController { | ||
98 | tenantProfile = checkNotNull(tenantProfileService.saveTenantProfile(getTenantId(), tenantProfile)); | 97 | tenantProfile = checkNotNull(tenantProfileService.saveTenantProfile(getTenantId(), tenantProfile)); |
99 | tenantProfileCache.put(tenantProfile); | 98 | tenantProfileCache.put(tenantProfile); |
100 | tbClusterService.onTenantProfileChange(tenantProfile, null); | 99 | tbClusterService.onTenantProfileChange(tenantProfile, null); |
101 | - tbClusterService.onEntityStateChange(TenantId.SYS_TENANT_ID, tenantProfile.getId(), | 100 | + tbClusterService.broadcastEntityStateChangeEvent(TenantId.SYS_TENANT_ID, tenantProfile.getId(), |
102 | newTenantProfile ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | 101 | newTenantProfile ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); |
103 | return tenantProfile; | 102 | return tenantProfile; |
104 | } catch (Exception e) { | 103 | } catch (Exception e) { |
@@ -41,7 +41,7 @@ import org.thingsboard.server.common.msg.TbMsgDataType; | @@ -41,7 +41,7 @@ import org.thingsboard.server.common.msg.TbMsgDataType; | ||
41 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 41 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
42 | import org.thingsboard.server.dao.audit.AuditLogService; | 42 | import org.thingsboard.server.dao.audit.AuditLogService; |
43 | import org.thingsboard.server.queue.util.TbCoreComponent; | 43 | import org.thingsboard.server.queue.util.TbCoreComponent; |
44 | -import org.thingsboard.server.service.queue.TbClusterService; | 44 | +import org.thingsboard.server.cluster.TbClusterService; |
45 | 45 | ||
46 | import java.util.List; | 46 | import java.util.List; |
47 | import java.util.Map; | 47 | import java.util.Map; |
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
@@ -61,7 +61,7 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | @@ -61,7 +61,7 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
61 | import org.thingsboard.server.queue.discovery.PartitionService; | 61 | import org.thingsboard.server.queue.discovery.PartitionService; |
62 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 62 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
63 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; | 63 | import org.thingsboard.server.queue.scheduler.SchedulerComponent; |
64 | -import org.thingsboard.server.service.queue.TbClusterService; | 64 | +import org.thingsboard.server.cluster.TbClusterService; |
65 | import org.thingsboard.server.service.telemetry.InternalTelemetryService; | 65 | import org.thingsboard.server.service.telemetry.InternalTelemetryService; |
66 | 66 | ||
67 | import javax.annotation.PostConstruct; | 67 | import javax.annotation.PostConstruct; |
@@ -29,6 +29,7 @@ import org.springframework.cache.CacheManager; | @@ -29,6 +29,7 @@ import org.springframework.cache.CacheManager; | ||
29 | import org.springframework.stereotype.Service; | 29 | import org.springframework.stereotype.Service; |
30 | import org.springframework.util.StringUtils; | 30 | import org.springframework.util.StringUtils; |
31 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | 31 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; |
32 | +import org.thingsboard.server.cluster.TbClusterService; | ||
32 | import org.thingsboard.server.common.data.Customer; | 33 | import org.thingsboard.server.common.data.Customer; |
33 | import org.thingsboard.server.common.data.DataConstants; | 34 | import org.thingsboard.server.common.data.DataConstants; |
34 | import org.thingsboard.server.common.data.Device; | 35 | import org.thingsboard.server.common.data.Device; |
@@ -70,6 +71,8 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | @@ -70,6 +71,8 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | ||
70 | private static final ObjectMapper mapper = new ObjectMapper(); | 71 | private static final ObjectMapper mapper = new ObjectMapper(); |
71 | 72 | ||
72 | @Autowired | 73 | @Autowired |
74 | + private TbClusterService clusterService; | ||
75 | + @Autowired | ||
73 | private DeviceService deviceService; | 76 | private DeviceService deviceService; |
74 | @Autowired | 77 | @Autowired |
75 | private AttributesService attributesService; | 78 | private AttributesService attributesService; |
@@ -155,6 +158,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | @@ -155,6 +158,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | ||
155 | if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { | 158 | if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { |
156 | device.setCustomerId(customerId); | 159 | device.setCustomerId(customerId); |
157 | Device savedDevice = deviceService.saveDevice(device); | 160 | Device savedDevice = deviceService.saveDevice(device); |
161 | + clusterService.onDeviceUpdated(savedDevice, device); | ||
158 | return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS), MoreExecutors.directExecutor()); | 162 | return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS), MoreExecutors.directExecutor()); |
159 | } | 163 | } |
160 | return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED), MoreExecutors.directExecutor()); | 164 | return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED), MoreExecutors.directExecutor()); |
@@ -179,13 +183,14 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | @@ -179,13 +183,14 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | ||
179 | cacheEviction(device.getId()); | 183 | cacheEviction(device.getId()); |
180 | Customer unassignedCustomer = customerService.findCustomerById(tenantId, device.getCustomerId()); | 184 | Customer unassignedCustomer = customerService.findCustomerById(tenantId, device.getCustomerId()); |
181 | device.setCustomerId(null); | 185 | device.setCustomerId(null); |
182 | - deviceService.saveDevice(device); | 186 | + Device savedDevice = deviceService.saveDevice(device); |
187 | + clusterService.onDeviceUpdated(savedDevice, device); | ||
183 | if (isAllowedClaimingByDefault) { | 188 | if (isAllowedClaimingByDefault) { |
184 | return Futures.immediateFuture(new ReclaimResult(unassignedCustomer)); | 189 | return Futures.immediateFuture(new ReclaimResult(unassignedCustomer)); |
185 | } | 190 | } |
186 | SettableFuture<ReclaimResult> result = SettableFuture.create(); | 191 | SettableFuture<ReclaimResult> result = SettableFuture.create(); |
187 | telemetryService.saveAndNotify( | 192 | telemetryService.saveAndNotify( |
188 | - tenantId, device.getId(), DataConstants.SERVER_SCOPE, Collections.singletonList( | 193 | + tenantId, savedDevice.getId(), DataConstants.SERVER_SCOPE, Collections.singletonList( |
189 | new BaseAttributeKvEntry(new BooleanDataEntry(CLAIM_ATTRIBUTE_NAME, true), System.currentTimeMillis()) | 194 | new BaseAttributeKvEntry(new BooleanDataEntry(CLAIM_ATTRIBUTE_NAME, true), System.currentTimeMillis()) |
190 | ), | 195 | ), |
191 | new FutureCallback<>() { | 196 | new FutureCallback<>() { |
@@ -198,7 +203,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | @@ -198,7 +203,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | ||
198 | public void onFailure(Throwable t) { | 203 | public void onFailure(Throwable t) { |
199 | result.setException(t); | 204 | result.setException(t); |
200 | } | 205 | } |
201 | - }); | 206 | + }); |
202 | return result; | 207 | return result; |
203 | } | 208 | } |
204 | cacheEviction(device.getId()); | 209 | cacheEviction(device.getId()); |
@@ -238,7 +243,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | @@ -238,7 +243,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { | ||
238 | public void onFailure(Throwable t) { | 243 | public void onFailure(Throwable t) { |
239 | result.setException(t); | 244 | result.setException(t); |
240 | } | 245 | } |
241 | - }); | 246 | + }); |
242 | return result; | 247 | return result; |
243 | } | 248 | } |
244 | 249 |
@@ -24,6 +24,7 @@ import org.apache.commons.lang3.RandomStringUtils; | @@ -24,6 +24,7 @@ import org.apache.commons.lang3.RandomStringUtils; | ||
24 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | import org.springframework.util.StringUtils; | 26 | import org.springframework.util.StringUtils; |
27 | +import org.thingsboard.server.cluster.TbClusterService; | ||
27 | import org.thingsboard.server.common.data.DataConstants; | 28 | import org.thingsboard.server.common.data.DataConstants; |
28 | import org.thingsboard.server.common.data.Device; | 29 | import org.thingsboard.server.common.data.Device; |
29 | import org.thingsboard.server.common.data.DeviceProfile; | 30 | import org.thingsboard.server.common.data.DeviceProfile; |
@@ -78,6 +79,9 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { | @@ -78,6 +79,9 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { | ||
78 | private static final String PROVISIONED_STATE = "provisioned"; | 79 | private static final String PROVISIONED_STATE = "provisioned"; |
79 | 80 | ||
80 | @Autowired | 81 | @Autowired |
82 | + TbClusterService clusterService; | ||
83 | + | ||
84 | + @Autowired | ||
81 | DeviceDao deviceDao; | 85 | DeviceDao deviceDao; |
82 | 86 | ||
83 | @Autowired | 87 | @Autowired |
@@ -190,8 +194,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { | @@ -190,8 +194,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { | ||
190 | provisionRequest.setDeviceName(newDeviceName); | 194 | provisionRequest.setDeviceName(newDeviceName); |
191 | } | 195 | } |
192 | Device savedDevice = deviceService.saveDevice(provisionRequest, profile); | 196 | Device savedDevice = deviceService.saveDevice(provisionRequest, profile); |
193 | - | ||
194 | - deviceStateService.onDeviceAdded(savedDevice); | 197 | + clusterService.onDeviceUpdated(savedDevice, null); |
195 | saveProvisionStateAttribute(savedDevice).get(); | 198 | saveProvisionStateAttribute(savedDevice).get(); |
196 | pushDeviceCreatedEventToRuleEngine(savedDevice); | 199 | pushDeviceCreatedEventToRuleEngine(savedDevice); |
197 | notify(savedDevice, provisionRequest, DataConstants.PROVISION_SUCCESS, true); | 200 | notify(savedDevice, provisionRequest, DataConstants.PROVISION_SUCCESS, true); |
@@ -16,11 +16,7 @@ | @@ -16,11 +16,7 @@ | ||
16 | package org.thingsboard.server.service.edge; | 16 | package org.thingsboard.server.service.edge; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | -import com.google.common.util.concurrent.FutureCallback; | ||
20 | -import com.google.common.util.concurrent.Futures; | ||
21 | -import com.google.common.util.concurrent.ListenableFuture; | ||
22 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
23 | -import org.checkerframework.checker.nullness.qual.Nullable; | ||
24 | import org.springframework.beans.factory.annotation.Autowired; | 20 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
26 | import org.thingsboard.server.common.data.edge.Edge; | 22 | import org.thingsboard.server.common.data.edge.Edge; |
@@ -41,8 +37,7 @@ import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; | @@ -41,8 +37,7 @@ import org.thingsboard.server.service.edge.rpc.processor.CustomerEdgeProcessor; | ||
41 | import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor; | 37 | import org.thingsboard.server.service.edge.rpc.processor.EdgeProcessor; |
42 | import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; | 38 | import org.thingsboard.server.service.edge.rpc.processor.EntityEdgeProcessor; |
43 | import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; | 39 | import org.thingsboard.server.service.edge.rpc.processor.RelationEdgeProcessor; |
44 | -import org.thingsboard.server.service.executors.DbCallbackExecutorService; | ||
45 | -import org.thingsboard.server.service.queue.TbClusterService; | 40 | +import org.thingsboard.server.cluster.TbClusterService; |
46 | 41 | ||
47 | import javax.annotation.PostConstruct; | 42 | import javax.annotation.PostConstruct; |
48 | import javax.annotation.PreDestroy; | 43 | import javax.annotation.PreDestroy; |
@@ -66,9 +61,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | @@ -66,9 +61,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | ||
66 | private TbClusterService clusterService; | 61 | private TbClusterService clusterService; |
67 | 62 | ||
68 | @Autowired | 63 | @Autowired |
69 | - private DbCallbackExecutorService dbCallbackExecutorService; | ||
70 | - | ||
71 | - @Autowired | ||
72 | private EdgeProcessor edgeProcessor; | 64 | private EdgeProcessor edgeProcessor; |
73 | 65 | ||
74 | @Autowired | 66 | @Autowired |
@@ -123,23 +115,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | @@ -123,23 +115,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { | ||
123 | edgeEvent.setEntityId(entityId.getId()); | 115 | edgeEvent.setEntityId(entityId.getId()); |
124 | } | 116 | } |
125 | edgeEvent.setBody(body); | 117 | edgeEvent.setBody(body); |
126 | - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent); | ||
127 | - Futures.addCallback(future, new FutureCallback<EdgeEvent>() { | ||
128 | - @Override | ||
129 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
130 | - clusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
131 | - } | ||
132 | - | ||
133 | - @Override | ||
134 | - public void onFailure(Throwable t) { | ||
135 | - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t); | ||
136 | - } | ||
137 | - }, dbCallbackExecutorService); | ||
138 | - | 118 | + edgeEventService.save(edgeEvent); |
119 | + clusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
139 | } | 120 | } |
140 | 121 | ||
141 | @Override | 122 | @Override |
142 | public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) { | 123 | public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) { |
124 | + log.trace("Pushing notification to edge {}", edgeNotificationMsg); | ||
143 | try { | 125 | try { |
144 | TenantId tenantId = new TenantId(new UUID(edgeNotificationMsg.getTenantIdMSB(), edgeNotificationMsg.getTenantIdLSB())); | 126 | TenantId tenantId = new TenantId(new UUID(edgeNotificationMsg.getTenantIdMSB(), edgeNotificationMsg.getTenantIdLSB())); |
145 | EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); | 127 | EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); |
@@ -259,7 +259,7 @@ public final class EdgeGrpcSession implements Closeable { | @@ -259,7 +259,7 @@ public final class EdgeGrpcSession implements Closeable { | ||
259 | log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg()); | 259 | log.error("[{}] Msg processing failed! Error msg: {}", edge.getRoutingKey(), msg.getErrorMsg()); |
260 | } | 260 | } |
261 | if (sessionState.getPendingMsgsMap().isEmpty()) { | 261 | if (sessionState.getPendingMsgsMap().isEmpty()) { |
262 | - log.debug("[{}] Pending msgs map is empty. Stopping current iteration {}", edge.getRoutingKey(), msg); | 262 | + log.debug("[{}] Pending msgs map is empty. Stopping current iteration", edge.getRoutingKey()); |
263 | if (sessionState.getScheduledSendDownlinkTask() != null) { | 263 | if (sessionState.getScheduledSendDownlinkTask() != null) { |
264 | sessionState.getScheduledSendDownlinkTask().cancel(false); | 264 | sessionState.getScheduledSendDownlinkTask().cancel(false); |
265 | } | 265 | } |
@@ -527,7 +527,7 @@ public final class EdgeGrpcSession implements Closeable { | @@ -527,7 +527,7 @@ public final class EdgeGrpcSession implements Closeable { | ||
527 | case RULE_CHAIN_METADATA: | 527 | case RULE_CHAIN_METADATA: |
528 | return ctx.getRuleChainProcessor().processRuleChainMetadataToEdge(edgeEvent, msgType); | 528 | return ctx.getRuleChainProcessor().processRuleChainMetadataToEdge(edgeEvent, msgType); |
529 | case ALARM: | 529 | case ALARM: |
530 | - return ctx.getAlarmProcessor().processAlarmToEdge(edge, edgeEvent, msgType); | 530 | + return ctx.getAlarmProcessor().processAlarmToEdge(edge, edgeEvent, msgType, action); |
531 | case USER: | 531 | case USER: |
532 | return ctx.getUserProcessor().processUserToEdge(edge, edgeEvent, msgType, action); | 532 | return ctx.getUserProcessor().processUserToEdge(edge, edgeEvent, msgType, action); |
533 | case RELATION: | 533 | case RELATION: |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.edge.rpc; | ||
17 | + | ||
18 | +import com.google.protobuf.BoolValue; | ||
19 | +import com.google.protobuf.ByteString; | ||
20 | +import com.google.protobuf.BytesValue; | ||
21 | +import com.google.protobuf.Int64Value; | ||
22 | +import com.google.protobuf.StringValue; | ||
23 | + | ||
24 | +public class EdgeProtoUtils { | ||
25 | + | ||
26 | + private EdgeProtoUtils() { | ||
27 | + } | ||
28 | + | ||
29 | + public static BoolValue getBoolValue(Boolean value) { | ||
30 | + BoolValue.Builder builder = BoolValue.newBuilder(); | ||
31 | + builder.setValue(value); | ||
32 | + return builder.build(); | ||
33 | + } | ||
34 | + | ||
35 | + public static StringValue getStringValue(String value) { | ||
36 | + StringValue.Builder builder = StringValue.newBuilder(); | ||
37 | + builder.setValue(value); | ||
38 | + return builder.build(); | ||
39 | + } | ||
40 | + | ||
41 | + public static Int64Value getInt64Value(Long value) { | ||
42 | + Int64Value.Builder builder = Int64Value.newBuilder(); | ||
43 | + builder.setValue(value); | ||
44 | + return builder.build(); | ||
45 | + } | ||
46 | + | ||
47 | + public static BytesValue getBytesValue(ByteString value) { | ||
48 | + BytesValue.Builder builder = BytesValue.newBuilder(); | ||
49 | + builder.setValue(value); | ||
50 | + return builder.build(); | ||
51 | + } | ||
52 | +} |
@@ -58,6 +58,8 @@ public class AlarmMsgConstructor { | @@ -58,6 +58,8 @@ public class AlarmMsgConstructor { | ||
58 | } | 58 | } |
59 | AlarmUpdateMsg.Builder builder = AlarmUpdateMsg.newBuilder() | 59 | AlarmUpdateMsg.Builder builder = AlarmUpdateMsg.newBuilder() |
60 | .setMsgType(msgType) | 60 | .setMsgType(msgType) |
61 | + .setIdMSB(alarm.getId().getId().getMostSignificantBits()) | ||
62 | + .setIdLSB(alarm.getId().getId().getLeastSignificantBits()) | ||
61 | .setName(alarm.getName()) | 63 | .setName(alarm.getName()) |
62 | .setType(alarm.getType()) | 64 | .setType(alarm.getType()) |
63 | .setOriginatorName(entityName) | 65 | .setOriginatorName(entityName) |
@@ -24,6 +24,9 @@ import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; | @@ -24,6 +24,9 @@ import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; | ||
24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
25 | import org.thingsboard.server.queue.util.TbCoreComponent; | 25 | import org.thingsboard.server.queue.util.TbCoreComponent; |
26 | 26 | ||
27 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
28 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
29 | + | ||
27 | @Component | 30 | @Component |
28 | @TbCoreComponent | 31 | @TbCoreComponent |
29 | public class AssetMsgConstructor { | 32 | public class AssetMsgConstructor { |
@@ -36,14 +39,14 @@ public class AssetMsgConstructor { | @@ -36,14 +39,14 @@ public class AssetMsgConstructor { | ||
36 | .setName(asset.getName()) | 39 | .setName(asset.getName()) |
37 | .setType(asset.getType()); | 40 | .setType(asset.getType()); |
38 | if (asset.getLabel() != null) { | 41 | if (asset.getLabel() != null) { |
39 | - builder.setLabel(asset.getLabel()); | 42 | + builder.setLabel(getStringValue(asset.getLabel())); |
40 | } | 43 | } |
41 | if (customerId != null) { | 44 | if (customerId != null) { |
42 | - builder.setCustomerIdMSB(customerId.getId().getMostSignificantBits()); | ||
43 | - builder.setCustomerIdLSB(customerId.getId().getLeastSignificantBits()); | 45 | + builder.setCustomerIdMSB(getInt64Value(customerId.getId().getMostSignificantBits())); |
46 | + builder.setCustomerIdLSB(getInt64Value(customerId.getId().getLeastSignificantBits())); | ||
44 | } | 47 | } |
45 | if (asset.getAdditionalInfo() != null) { | 48 | if (asset.getAdditionalInfo() != null) { |
46 | - builder.setAdditionalInfo(JacksonUtil.toString(asset.getAdditionalInfo())); | 49 | + builder.setAdditionalInfo(getStringValue(JacksonUtil.toString(asset.getAdditionalInfo()))); |
47 | } | 50 | } |
48 | return builder.build(); | 51 | return builder.build(); |
49 | } | 52 | } |
@@ -23,6 +23,8 @@ import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; | @@ -23,6 +23,8 @@ import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; | ||
23 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 23 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
24 | import org.thingsboard.server.queue.util.TbCoreComponent; | 24 | import org.thingsboard.server.queue.util.TbCoreComponent; |
25 | 25 | ||
26 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
27 | + | ||
26 | @Component | 28 | @Component |
27 | @TbCoreComponent | 29 | @TbCoreComponent |
28 | public class CustomerMsgConstructor { | 30 | public class CustomerMsgConstructor { |
@@ -34,31 +36,31 @@ public class CustomerMsgConstructor { | @@ -34,31 +36,31 @@ public class CustomerMsgConstructor { | ||
34 | .setIdLSB(customer.getId().getId().getLeastSignificantBits()) | 36 | .setIdLSB(customer.getId().getId().getLeastSignificantBits()) |
35 | .setTitle(customer.getTitle()); | 37 | .setTitle(customer.getTitle()); |
36 | if (customer.getCountry() != null) { | 38 | if (customer.getCountry() != null) { |
37 | - builder.setCountry(customer.getCountry()); | 39 | + builder.setCountry(getStringValue(customer.getCountry())); |
38 | } | 40 | } |
39 | if (customer.getState() != null) { | 41 | if (customer.getState() != null) { |
40 | - builder.setState(customer.getState()); | 42 | + builder.setState(getStringValue(customer.getState())); |
41 | } | 43 | } |
42 | if (customer.getCity() != null) { | 44 | if (customer.getCity() != null) { |
43 | - builder.setCity(customer.getCity()); | 45 | + builder.setCity(getStringValue(customer.getCity())); |
44 | } | 46 | } |
45 | if (customer.getAddress() != null) { | 47 | if (customer.getAddress() != null) { |
46 | - builder.setAddress(customer.getAddress()); | 48 | + builder.setAddress(getStringValue(customer.getAddress())); |
47 | } | 49 | } |
48 | if (customer.getAddress2() != null) { | 50 | if (customer.getAddress2() != null) { |
49 | - builder.setAddress2(customer.getAddress2()); | 51 | + builder.setAddress2(getStringValue(customer.getAddress2())); |
50 | } | 52 | } |
51 | if (customer.getZip() != null) { | 53 | if (customer.getZip() != null) { |
52 | - builder.setZip(customer.getZip()); | 54 | + builder.setZip(getStringValue(customer.getZip())); |
53 | } | 55 | } |
54 | if (customer.getPhone() != null) { | 56 | if (customer.getPhone() != null) { |
55 | - builder.setPhone(customer.getPhone()); | 57 | + builder.setPhone(getStringValue(customer.getPhone())); |
56 | } | 58 | } |
57 | if (customer.getEmail() != null) { | 59 | if (customer.getEmail() != null) { |
58 | - builder.setEmail(customer.getEmail()); | 60 | + builder.setEmail(getStringValue(customer.getEmail())); |
59 | } | 61 | } |
60 | if (customer.getAdditionalInfo() != null) { | 62 | if (customer.getAdditionalInfo() != null) { |
61 | - builder.setAdditionalInfo(JacksonUtil.toString(customer.getAdditionalInfo())); | 63 | + builder.setAdditionalInfo(getStringValue(JacksonUtil.toString(customer.getAdditionalInfo()))); |
62 | } | 64 | } |
63 | return builder.build(); | 65 | return builder.build(); |
64 | } | 66 | } |
@@ -24,6 +24,8 @@ import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; | @@ -24,6 +24,8 @@ import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; | ||
24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
25 | import org.thingsboard.server.queue.util.TbCoreComponent; | 25 | import org.thingsboard.server.queue.util.TbCoreComponent; |
26 | 26 | ||
27 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
28 | + | ||
27 | @Component | 29 | @Component |
28 | @TbCoreComponent | 30 | @TbCoreComponent |
29 | public class DashboardMsgConstructor { | 31 | public class DashboardMsgConstructor { |
@@ -36,8 +38,8 @@ public class DashboardMsgConstructor { | @@ -36,8 +38,8 @@ public class DashboardMsgConstructor { | ||
36 | .setTitle(dashboard.getTitle()) | 38 | .setTitle(dashboard.getTitle()) |
37 | .setConfiguration(JacksonUtil.toString(dashboard.getConfiguration())); | 39 | .setConfiguration(JacksonUtil.toString(dashboard.getConfiguration())); |
38 | if (customerId != null) { | 40 | if (customerId != null) { |
39 | - builder.setCustomerIdMSB(customerId.getId().getMostSignificantBits()); | ||
40 | - builder.setCustomerIdLSB(customerId.getId().getLeastSignificantBits()); | 41 | + builder.setCustomerIdMSB(getInt64Value(customerId.getId().getMostSignificantBits())); |
42 | + builder.setCustomerIdLSB(getInt64Value(customerId.getId().getLeastSignificantBits())); | ||
41 | } | 43 | } |
42 | return builder.build(); | 44 | return builder.build(); |
43 | } | 45 | } |
@@ -32,6 +32,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -32,6 +32,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
32 | 32 | ||
33 | import java.util.UUID; | 33 | import java.util.UUID; |
34 | 34 | ||
35 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
36 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
37 | + | ||
35 | @Component | 38 | @Component |
36 | @TbCoreComponent | 39 | @TbCoreComponent |
37 | public class DeviceMsgConstructor { | 40 | public class DeviceMsgConstructor { |
@@ -46,21 +49,21 @@ public class DeviceMsgConstructor { | @@ -46,21 +49,21 @@ public class DeviceMsgConstructor { | ||
46 | .setName(device.getName()) | 49 | .setName(device.getName()) |
47 | .setType(device.getType()); | 50 | .setType(device.getType()); |
48 | if (device.getLabel() != null) { | 51 | if (device.getLabel() != null) { |
49 | - builder.setLabel(device.getLabel()); | 52 | + builder.setLabel(getStringValue(device.getLabel())); |
50 | } | 53 | } |
51 | if (customerId != null) { | 54 | if (customerId != null) { |
52 | - builder.setCustomerIdMSB(customerId.getId().getMostSignificantBits()); | ||
53 | - builder.setCustomerIdLSB(customerId.getId().getLeastSignificantBits()); | 55 | + builder.setCustomerIdMSB(getInt64Value(customerId.getId().getMostSignificantBits())); |
56 | + builder.setCustomerIdLSB(getInt64Value(customerId.getId().getLeastSignificantBits())); | ||
54 | } | 57 | } |
55 | if (device.getDeviceProfileId() != null) { | 58 | if (device.getDeviceProfileId() != null) { |
56 | - builder.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()); | ||
57 | - builder.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()); | 59 | + builder.setDeviceProfileIdMSB(getInt64Value(device.getDeviceProfileId().getId().getMostSignificantBits())); |
60 | + builder.setDeviceProfileIdLSB(getInt64Value(device.getDeviceProfileId().getId().getLeastSignificantBits())); | ||
58 | } | 61 | } |
59 | if (device.getAdditionalInfo() != null) { | 62 | if (device.getAdditionalInfo() != null) { |
60 | - builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); | 63 | + builder.setAdditionalInfo(getStringValue(JacksonUtil.toString(device.getAdditionalInfo()))); |
61 | } | 64 | } |
62 | if (conflictName != null) { | 65 | if (conflictName != null) { |
63 | - builder.setConflictName(conflictName); | 66 | + builder.setConflictName(getStringValue(conflictName)); |
64 | } | 67 | } |
65 | return builder.build(); | 68 | return builder.build(); |
66 | } | 69 | } |
@@ -74,7 +77,7 @@ public class DeviceMsgConstructor { | @@ -74,7 +77,7 @@ public class DeviceMsgConstructor { | ||
74 | .setCredentialsId(deviceCredentials.getCredentialsId()); | 77 | .setCredentialsId(deviceCredentials.getCredentialsId()); |
75 | } | 78 | } |
76 | if (deviceCredentials.getCredentialsValue() != null) { | 79 | if (deviceCredentials.getCredentialsValue() != null) { |
77 | - builder.setCredentialsValue(deviceCredentials.getCredentialsValue()); | 80 | + builder.setCredentialsValue(getStringValue(deviceCredentials.getCredentialsValue())); |
78 | } | 81 | } |
79 | return builder.build(); | 82 | return builder.build(); |
80 | } | 83 | } |
@@ -27,6 +27,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -27,6 +27,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
27 | 27 | ||
28 | import java.nio.charset.StandardCharsets; | 28 | import java.nio.charset.StandardCharsets; |
29 | 29 | ||
30 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getBytesValue; | ||
31 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
32 | + | ||
30 | @Component | 33 | @Component |
31 | @TbCoreComponent | 34 | @TbCoreComponent |
32 | public class DeviceProfileMsgConstructor { | 35 | public class DeviceProfileMsgConstructor { |
@@ -52,19 +55,19 @@ public class DeviceProfileMsgConstructor { | @@ -52,19 +55,19 @@ public class DeviceProfileMsgConstructor { | ||
52 | // builder.setDefaultQueueName(deviceProfile.getDefaultQueueName()); | 55 | // builder.setDefaultQueueName(deviceProfile.getDefaultQueueName()); |
53 | // } | 56 | // } |
54 | if (deviceProfile.getDescription() != null) { | 57 | if (deviceProfile.getDescription() != null) { |
55 | - builder.setDescription(deviceProfile.getDescription()); | 58 | + builder.setDescription(getStringValue(deviceProfile.getDescription())); |
56 | } | 59 | } |
57 | if (deviceProfile.getTransportType() != null) { | 60 | if (deviceProfile.getTransportType() != null) { |
58 | - builder.setTransportType(deviceProfile.getTransportType().name()); | 61 | + builder.setTransportType(getStringValue(deviceProfile.getTransportType().name())); |
59 | } | 62 | } |
60 | if (deviceProfile.getProvisionType() != null) { | 63 | if (deviceProfile.getProvisionType() != null) { |
61 | - builder.setProvisionType(deviceProfile.getProvisionType().name()); | 64 | + builder.setProvisionType(getStringValue(deviceProfile.getProvisionType().name())); |
62 | } | 65 | } |
63 | if (deviceProfile.getProvisionDeviceKey() != null) { | 66 | if (deviceProfile.getProvisionDeviceKey() != null) { |
64 | - builder.setProvisionDeviceKey(deviceProfile.getProvisionDeviceKey()); | 67 | + builder.setProvisionDeviceKey(getStringValue(deviceProfile.getProvisionDeviceKey())); |
65 | } | 68 | } |
66 | if (deviceProfile.getImage() != null) { | 69 | if (deviceProfile.getImage() != null) { |
67 | - builder.setImage(ByteString.copyFrom(deviceProfile.getImage().getBytes(StandardCharsets.UTF_8))); | 70 | + builder.setImage(getBytesValue(ByteString.copyFrom(deviceProfile.getImage().getBytes(StandardCharsets.UTF_8)))); |
68 | } | 71 | } |
69 | return builder.build(); | 72 | return builder.build(); |
70 | } | 73 | } |
@@ -25,6 +25,9 @@ import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; | @@ -25,6 +25,9 @@ import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; | ||
25 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 25 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
26 | import org.thingsboard.server.queue.util.TbCoreComponent; | 26 | import org.thingsboard.server.queue.util.TbCoreComponent; |
27 | 27 | ||
28 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
29 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
30 | + | ||
28 | @Component | 31 | @Component |
29 | @TbCoreComponent | 32 | @TbCoreComponent |
30 | public class EntityViewMsgConstructor { | 33 | public class EntityViewMsgConstructor { |
@@ -51,11 +54,11 @@ public class EntityViewMsgConstructor { | @@ -51,11 +54,11 @@ public class EntityViewMsgConstructor { | ||
51 | .setEntityIdLSB(entityView.getEntityId().getId().getLeastSignificantBits()) | 54 | .setEntityIdLSB(entityView.getEntityId().getId().getLeastSignificantBits()) |
52 | .setEntityType(entityType); | 55 | .setEntityType(entityType); |
53 | if (customerId != null) { | 56 | if (customerId != null) { |
54 | - builder.setCustomerIdMSB(customerId.getId().getMostSignificantBits()); | ||
55 | - builder.setCustomerIdLSB(customerId.getId().getLeastSignificantBits()); | 57 | + builder.setCustomerIdMSB(getInt64Value(customerId.getId().getMostSignificantBits())); |
58 | + builder.setCustomerIdLSB(getInt64Value(customerId.getId().getLeastSignificantBits())); | ||
56 | } | 59 | } |
57 | if (entityView.getAdditionalInfo() != null) { | 60 | if (entityView.getAdditionalInfo() != null) { |
58 | - builder.setAdditionalInfo(JacksonUtil.toString(entityView.getAdditionalInfo())); | 61 | + builder.setAdditionalInfo(getStringValue(JacksonUtil.toString(entityView.getAdditionalInfo()))); |
59 | } | 62 | } |
60 | return builder.build(); | 63 | return builder.build(); |
61 | } | 64 | } |
@@ -22,6 +22,8 @@ import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; | @@ -22,6 +22,8 @@ import org.thingsboard.server.gen.edge.v1.RelationUpdateMsg; | ||
22 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 22 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
23 | import org.thingsboard.server.queue.util.TbCoreComponent; | 23 | import org.thingsboard.server.queue.util.TbCoreComponent; |
24 | 24 | ||
25 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
26 | + | ||
25 | @Component | 27 | @Component |
26 | @TbCoreComponent | 28 | @TbCoreComponent |
27 | public class RelationMsgConstructor { | 29 | public class RelationMsgConstructor { |
@@ -35,10 +37,12 @@ public class RelationMsgConstructor { | @@ -35,10 +37,12 @@ public class RelationMsgConstructor { | ||
35 | .setToIdMSB(entityRelation.getTo().getId().getMostSignificantBits()) | 37 | .setToIdMSB(entityRelation.getTo().getId().getMostSignificantBits()) |
36 | .setToIdLSB(entityRelation.getTo().getId().getLeastSignificantBits()) | 38 | .setToIdLSB(entityRelation.getTo().getId().getLeastSignificantBits()) |
37 | .setToEntityType(entityRelation.getTo().getEntityType().name()) | 39 | .setToEntityType(entityRelation.getTo().getEntityType().name()) |
38 | - .setType(entityRelation.getType()) | ||
39 | - .setAdditionalInfo(JacksonUtil.toString(entityRelation.getAdditionalInfo())); | 40 | + .setType(entityRelation.getType()); |
41 | + if (entityRelation.getAdditionalInfo() != null) { | ||
42 | + builder.setAdditionalInfo(JacksonUtil.toString(entityRelation.getAdditionalInfo())); | ||
43 | + } | ||
40 | if (entityRelation.getTypeGroup() != null) { | 44 | if (entityRelation.getTypeGroup() != null) { |
41 | - builder.setTypeGroup(entityRelation.getTypeGroup().name()); | 45 | + builder.setTypeGroup(getStringValue(entityRelation.getTypeGroup().name())); |
42 | } | 46 | } |
43 | return builder.build(); | 47 | return builder.build(); |
44 | } | 48 | } |
@@ -37,6 +37,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -37,6 +37,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
37 | import java.util.ArrayList; | 37 | import java.util.ArrayList; |
38 | import java.util.List; | 38 | import java.util.List; |
39 | 39 | ||
40 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
41 | + | ||
40 | @Component | 42 | @Component |
41 | @Slf4j | 43 | @Slf4j |
42 | @TbCoreComponent | 44 | @TbCoreComponent |
@@ -54,8 +56,8 @@ public class RuleChainMsgConstructor { | @@ -54,8 +56,8 @@ public class RuleChainMsgConstructor { | ||
54 | .setDebugMode(ruleChain.isDebugMode()) | 56 | .setDebugMode(ruleChain.isDebugMode()) |
55 | .setConfiguration(JacksonUtil.toString(ruleChain.getConfiguration())); | 57 | .setConfiguration(JacksonUtil.toString(ruleChain.getConfiguration())); |
56 | if (ruleChain.getFirstRuleNodeId() != null) { | 58 | if (ruleChain.getFirstRuleNodeId() != null) { |
57 | - builder.setFirstRuleNodeIdMSB(ruleChain.getFirstRuleNodeId().getId().getMostSignificantBits()) | ||
58 | - .setFirstRuleNodeIdLSB(ruleChain.getFirstRuleNodeId().getId().getLeastSignificantBits()); | 59 | + builder.setFirstRuleNodeIdMSB(getInt64Value(ruleChain.getFirstRuleNodeId().getId().getMostSignificantBits())) |
60 | + .setFirstRuleNodeIdLSB(getInt64Value(ruleChain.getFirstRuleNodeId().getId().getLeastSignificantBits())); | ||
59 | } | 61 | } |
60 | return builder.build(); | 62 | return builder.build(); |
61 | } | 63 | } |
@@ -16,16 +16,19 @@ | @@ -16,16 +16,19 @@ | ||
16 | package org.thingsboard.server.service.edge.rpc.constructor; | 16 | package org.thingsboard.server.service.edge.rpc.constructor; |
17 | 17 | ||
18 | import org.springframework.stereotype.Component; | 18 | import org.springframework.stereotype.Component; |
19 | +import org.thingsboard.common.util.JacksonUtil; | ||
19 | import org.thingsboard.server.common.data.User; | 20 | import org.thingsboard.server.common.data.User; |
20 | import org.thingsboard.server.common.data.id.CustomerId; | 21 | import org.thingsboard.server.common.data.id.CustomerId; |
21 | import org.thingsboard.server.common.data.id.UserId; | 22 | import org.thingsboard.server.common.data.id.UserId; |
22 | import org.thingsboard.server.common.data.security.UserCredentials; | 23 | import org.thingsboard.server.common.data.security.UserCredentials; |
23 | -import org.thingsboard.common.util.JacksonUtil; | ||
24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 24 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
25 | import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; | 25 | import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; |
26 | import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; | 26 | import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; |
27 | import org.thingsboard.server.queue.util.TbCoreComponent; | 27 | import org.thingsboard.server.queue.util.TbCoreComponent; |
28 | 28 | ||
29 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getInt64Value; | ||
30 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
31 | + | ||
29 | @Component | 32 | @Component |
30 | @TbCoreComponent | 33 | @TbCoreComponent |
31 | public class UserMsgConstructor { | 34 | public class UserMsgConstructor { |
@@ -38,20 +41,17 @@ public class UserMsgConstructor { | @@ -38,20 +41,17 @@ public class UserMsgConstructor { | ||
38 | .setEmail(user.getEmail()) | 41 | .setEmail(user.getEmail()) |
39 | .setAuthority(user.getAuthority().name()); | 42 | .setAuthority(user.getAuthority().name()); |
40 | if (customerId != null) { | 43 | if (customerId != null) { |
41 | - builder.setCustomerIdMSB(customerId.getId().getMostSignificantBits()); | ||
42 | - builder.setCustomerIdLSB(customerId.getId().getLeastSignificantBits()); | 44 | + builder.setCustomerIdMSB(getInt64Value(customerId.getId().getMostSignificantBits())); |
45 | + builder.setCustomerIdLSB(getInt64Value(customerId.getId().getLeastSignificantBits())); | ||
43 | } | 46 | } |
44 | if (user.getFirstName() != null) { | 47 | if (user.getFirstName() != null) { |
45 | - builder.setFirstName(user.getFirstName()); | 48 | + builder.setFirstName(getStringValue(user.getFirstName())); |
46 | } | 49 | } |
47 | if (user.getLastName() != null) { | 50 | if (user.getLastName() != null) { |
48 | - builder.setLastName(user.getLastName()); | ||
49 | - } | ||
50 | - if (user.getAdditionalInfo() != null) { | ||
51 | - builder.setAdditionalInfo(JacksonUtil.toString(user.getAdditionalInfo())); | 51 | + builder.setLastName(getStringValue(user.getLastName())); |
52 | } | 52 | } |
53 | if (user.getAdditionalInfo() != null) { | 53 | if (user.getAdditionalInfo() != null) { |
54 | - builder.setAdditionalInfo(JacksonUtil.toString(user.getAdditionalInfo())); | 54 | + builder.setAdditionalInfo(getStringValue(JacksonUtil.toString(user.getAdditionalInfo()))); |
55 | } | 55 | } |
56 | return builder.build(); | 56 | return builder.build(); |
57 | } | 57 | } |
@@ -16,14 +16,16 @@ | @@ -16,14 +16,16 @@ | ||
16 | package org.thingsboard.server.service.edge.rpc.constructor; | 16 | package org.thingsboard.server.service.edge.rpc.constructor; |
17 | 17 | ||
18 | import org.springframework.stereotype.Component; | 18 | import org.springframework.stereotype.Component; |
19 | +import org.thingsboard.common.util.JacksonUtil; | ||
19 | import org.thingsboard.server.common.data.id.TenantId; | 20 | import org.thingsboard.server.common.data.id.TenantId; |
20 | import org.thingsboard.server.common.data.id.WidgetTypeId; | 21 | import org.thingsboard.server.common.data.id.WidgetTypeId; |
21 | import org.thingsboard.server.common.data.widget.WidgetType; | 22 | import org.thingsboard.server.common.data.widget.WidgetType; |
22 | -import org.thingsboard.common.util.JacksonUtil; | ||
23 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | 23 | import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
24 | import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; | 24 | import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; |
25 | import org.thingsboard.server.queue.util.TbCoreComponent; | 25 | import org.thingsboard.server.queue.util.TbCoreComponent; |
26 | 26 | ||
27 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
28 | + | ||
27 | @Component | 29 | @Component |
28 | @TbCoreComponent | 30 | @TbCoreComponent |
29 | public class WidgetTypeMsgConstructor { | 31 | public class WidgetTypeMsgConstructor { |
@@ -33,21 +35,21 @@ public class WidgetTypeMsgConstructor { | @@ -33,21 +35,21 @@ public class WidgetTypeMsgConstructor { | ||
33 | .setMsgType(msgType) | 35 | .setMsgType(msgType) |
34 | .setIdMSB(widgetType.getId().getId().getMostSignificantBits()) | 36 | .setIdMSB(widgetType.getId().getId().getMostSignificantBits()) |
35 | .setIdLSB(widgetType.getId().getId().getLeastSignificantBits()); | 37 | .setIdLSB(widgetType.getId().getId().getLeastSignificantBits()); |
36 | - if (widgetType.getBundleAlias() != null) { | ||
37 | - builder.setBundleAlias(widgetType.getBundleAlias()); | ||
38 | - } | ||
39 | - if (widgetType.getAlias() != null) { | ||
40 | - builder.setAlias(widgetType.getAlias()); | ||
41 | - } | ||
42 | - if (widgetType.getName() != null) { | ||
43 | - builder.setName(widgetType.getName()); | ||
44 | - } | ||
45 | - if (widgetType.getDescriptor() != null) { | ||
46 | - builder.setDescriptorJson(JacksonUtil.toString(widgetType.getDescriptor())); | ||
47 | - } | ||
48 | - if (widgetType.getTenantId().equals(TenantId.SYS_TENANT_ID)) { | ||
49 | - builder.setIsSystem(true); | ||
50 | - } | 38 | + if (widgetType.getBundleAlias() != null) { |
39 | + builder.setBundleAlias(getStringValue(widgetType.getBundleAlias())); | ||
40 | + } | ||
41 | + if (widgetType.getAlias() != null) { | ||
42 | + builder.setAlias(getStringValue(widgetType.getAlias())); | ||
43 | + } | ||
44 | + if (widgetType.getName() != null) { | ||
45 | + builder.setName(getStringValue(widgetType.getName())); | ||
46 | + } | ||
47 | + if (widgetType.getDescriptor() != null) { | ||
48 | + builder.setDescriptorJson(getStringValue(JacksonUtil.toString(widgetType.getDescriptor()))); | ||
49 | + } | ||
50 | + if (widgetType.getTenantId().equals(TenantId.SYS_TENANT_ID)) { | ||
51 | + builder.setIsSystem(true); | ||
52 | + } | ||
51 | return builder.build(); | 53 | return builder.build(); |
52 | } | 54 | } |
53 | 55 |
@@ -26,6 +26,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -26,6 +26,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
26 | 26 | ||
27 | import java.nio.charset.StandardCharsets; | 27 | import java.nio.charset.StandardCharsets; |
28 | 28 | ||
29 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getBytesValue; | ||
30 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
31 | + | ||
29 | @Component | 32 | @Component |
30 | @TbCoreComponent | 33 | @TbCoreComponent |
31 | public class WidgetsBundleMsgConstructor { | 34 | public class WidgetsBundleMsgConstructor { |
@@ -38,10 +41,10 @@ public class WidgetsBundleMsgConstructor { | @@ -38,10 +41,10 @@ public class WidgetsBundleMsgConstructor { | ||
38 | .setTitle(widgetsBundle.getTitle()) | 41 | .setTitle(widgetsBundle.getTitle()) |
39 | .setAlias(widgetsBundle.getAlias()); | 42 | .setAlias(widgetsBundle.getAlias()); |
40 | if (widgetsBundle.getImage() != null) { | 43 | if (widgetsBundle.getImage() != null) { |
41 | - builder.setImage(ByteString.copyFrom(widgetsBundle.getImage().getBytes(StandardCharsets.UTF_8))); | 44 | + builder.setImage(getBytesValue(ByteString.copyFrom(widgetsBundle.getImage().getBytes(StandardCharsets.UTF_8)))); |
42 | } | 45 | } |
43 | if (widgetsBundle.getDescription() != null) { | 46 | if (widgetsBundle.getDescription() != null) { |
44 | - builder.setDescription(widgetsBundle.getDescription()); | 47 | + builder.setDescription(getStringValue(widgetsBundle.getDescription())); |
45 | } | 48 | } |
46 | if (widgetsBundle.getTenantId().equals(TenantId.SYS_TENANT_ID)) { | 49 | if (widgetsBundle.getTenantId().equals(TenantId.SYS_TENANT_ID)) { |
47 | builder.setIsSystem(true); | 50 | builder.setIsSystem(true); |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.edge.rpc.processor; | 16 | package org.thingsboard.server.service.edge.rpc.processor; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
18 | import com.google.common.util.concurrent.FutureCallback; | 19 | import com.google.common.util.concurrent.FutureCallback; |
19 | import com.google.common.util.concurrent.Futures; | 20 | import com.google.common.util.concurrent.Futures; |
20 | import com.google.common.util.concurrent.ListenableFuture; | 21 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -54,6 +55,7 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { | @@ -54,6 +55,7 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { | ||
54 | EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(), | 55 | EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(), |
55 | EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); | 56 | EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); |
56 | if (originatorId == null) { | 57 | if (originatorId == null) { |
58 | + log.warn("Originator not found for the alarm msg {}", alarmUpdateMsg); | ||
57 | return Futures.immediateFuture(null); | 59 | return Futures.immediateFuture(null); |
58 | } | 60 | } |
59 | try { | 61 | try { |
@@ -113,59 +115,84 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { | @@ -113,59 +115,84 @@ public class AlarmEdgeProcessor extends BaseEdgeProcessor { | ||
113 | } | 115 | } |
114 | } | 116 | } |
115 | 117 | ||
116 | - public DownlinkMsg processAlarmToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType) { | 118 | + public DownlinkMsg processAlarmToEdge(Edge edge, EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { |
119 | + AlarmId alarmId = new AlarmId(edgeEvent.getEntityId()); | ||
117 | DownlinkMsg downlinkMsg = null; | 120 | DownlinkMsg downlinkMsg = null; |
118 | - try { | ||
119 | - AlarmId alarmId = new AlarmId(edgeEvent.getEntityId()); | ||
120 | - Alarm alarm = alarmService.findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); | ||
121 | - if (alarm != null) { | 121 | + switch (action) { |
122 | + case ADDED: | ||
123 | + case UPDATED: | ||
124 | + case ALARM_ACK: | ||
125 | + case ALARM_CLEAR: | ||
126 | + try { | ||
127 | + Alarm alarm = alarmService.findAlarmByIdAsync(edgeEvent.getTenantId(), alarmId).get(); | ||
128 | + if (alarm != null) { | ||
129 | + downlinkMsg = DownlinkMsg.newBuilder() | ||
130 | + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) | ||
131 | + .addAlarmUpdateMsg(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm)) | ||
132 | + .build(); | ||
133 | + } | ||
134 | + } catch (Exception e) { | ||
135 | + log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); | ||
136 | + } | ||
137 | + break; | ||
138 | + case DELETED: | ||
139 | + Alarm alarm = mapper.convertValue(edgeEvent.getBody(), Alarm.class); | ||
140 | + AlarmUpdateMsg alarmUpdateMsg = | ||
141 | + alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm); | ||
122 | downlinkMsg = DownlinkMsg.newBuilder() | 142 | downlinkMsg = DownlinkMsg.newBuilder() |
123 | .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) | 143 | .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) |
124 | - .addAlarmUpdateMsg(alarmMsgConstructor.constructAlarmUpdatedMsg(edge.getTenantId(), msgType, alarm)) | 144 | + .addAlarmUpdateMsg(alarmUpdateMsg) |
125 | .build(); | 145 | .build(); |
126 | - } | ||
127 | - } catch (Exception e) { | ||
128 | - log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); | 146 | + break; |
129 | } | 147 | } |
130 | return downlinkMsg; | 148 | return downlinkMsg; |
131 | } | 149 | } |
132 | 150 | ||
133 | - public void processAlarmNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { | 151 | + public void processAlarmNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) throws JsonProcessingException { |
152 | + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); | ||
134 | AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); | 153 | AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); |
135 | - ListenableFuture<Alarm> alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); | ||
136 | - Futures.addCallback(alarmFuture, new FutureCallback<Alarm>() { | ||
137 | - @Override | ||
138 | - public void onSuccess(@Nullable Alarm alarm) { | ||
139 | - if (alarm != null) { | ||
140 | - EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); | ||
141 | - if (type != null) { | ||
142 | - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); | ||
143 | - PageData<EdgeId> pageData; | ||
144 | - do { | ||
145 | - pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator(), pageLink); | ||
146 | - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { | ||
147 | - for (EdgeId edgeId : pageData.getData()) { | ||
148 | - saveEdgeEvent(tenantId, | ||
149 | - edgeId, | ||
150 | - EdgeEventType.ALARM, | ||
151 | - EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), | ||
152 | - alarmId, | ||
153 | - null); | ||
154 | - } | ||
155 | - if (pageData.hasNext()) { | ||
156 | - pageLink = pageLink.nextPageLink(); | ||
157 | - } | 154 | + switch (actionType) { |
155 | + case DELETED: | ||
156 | + EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB())); | ||
157 | + Alarm alarm = mapper.readValue(edgeNotificationMsg.getBody(), Alarm.class); | ||
158 | + saveEdgeEvent(tenantId, edgeId, EdgeEventType.ALARM, actionType, alarmId, mapper.valueToTree(alarm)); | ||
159 | + break; | ||
160 | + default: | ||
161 | + ListenableFuture<Alarm> alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); | ||
162 | + Futures.addCallback(alarmFuture, new FutureCallback<Alarm>() { | ||
163 | + @Override | ||
164 | + public void onSuccess(@Nullable Alarm alarm) { | ||
165 | + if (alarm != null) { | ||
166 | + EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); | ||
167 | + if (type != null) { | ||
168 | + PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); | ||
169 | + PageData<EdgeId> pageData; | ||
170 | + do { | ||
171 | + pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator(), pageLink); | ||
172 | + if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { | ||
173 | + for (EdgeId edgeId : pageData.getData()) { | ||
174 | + saveEdgeEvent(tenantId, | ||
175 | + edgeId, | ||
176 | + EdgeEventType.ALARM, | ||
177 | + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), | ||
178 | + alarmId, | ||
179 | + null); | ||
180 | + } | ||
181 | + if (pageData.hasNext()) { | ||
182 | + pageLink = pageLink.nextPageLink(); | ||
183 | + } | ||
184 | + } | ||
185 | + } while (pageData != null && pageData.hasNext()); | ||
158 | } | 186 | } |
159 | - } while (pageData != null && pageData.hasNext()); | 187 | + } |
160 | } | 188 | } |
161 | - } | ||
162 | - } | ||
163 | 189 | ||
164 | - @Override | ||
165 | - public void onFailure(Throwable t) { | ||
166 | - log.warn("[{}] can't find alarm by id [{}] {}", tenantId.getId(), alarmId.getId(), t); | ||
167 | - } | ||
168 | - }, dbCallbackExecutorService); | 190 | + @Override |
191 | + public void onFailure(Throwable t) { | ||
192 | + log.warn("[{}] can't find alarm by id [{}] {}", tenantId.getId(), alarmId.getId(), t); | ||
193 | + } | ||
194 | + }, dbCallbackExecutorService); | ||
195 | + } | ||
169 | } | 196 | } |
170 | 197 | ||
171 | } | 198 | } |
@@ -17,11 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; | @@ -17,11 +17,7 @@ package org.thingsboard.server.service.edge.rpc.processor; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | -import com.google.common.util.concurrent.FutureCallback; | ||
21 | -import com.google.common.util.concurrent.Futures; | ||
22 | -import com.google.common.util.concurrent.ListenableFuture; | ||
23 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
24 | -import org.checkerframework.checker.nullness.qual.Nullable; | ||
25 | import org.springframework.beans.factory.annotation.Autowired; | 21 | import org.springframework.beans.factory.annotation.Autowired; |
26 | import org.thingsboard.server.common.data.HasCustomerId; | 22 | import org.thingsboard.server.common.data.HasCustomerId; |
27 | import org.thingsboard.server.common.data.edge.Edge; | 23 | import org.thingsboard.server.common.data.edge.Edge; |
@@ -66,7 +62,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstruc | @@ -66,7 +62,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.WidgetTypeMsgConstruc | ||
66 | import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; | 62 | import org.thingsboard.server.service.edge.rpc.constructor.WidgetsBundleMsgConstructor; |
67 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 63 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
68 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 64 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
69 | -import org.thingsboard.server.service.queue.TbClusterService; | 65 | +import org.thingsboard.server.cluster.TbClusterService; |
70 | import org.thingsboard.server.service.state.DeviceStateService; | 66 | import org.thingsboard.server.service.state.DeviceStateService; |
71 | 67 | ||
72 | @Slf4j | 68 | @Slf4j |
@@ -178,12 +174,12 @@ public abstract class BaseEdgeProcessor { | @@ -178,12 +174,12 @@ public abstract class BaseEdgeProcessor { | ||
178 | @Autowired | 174 | @Autowired |
179 | protected DbCallbackExecutorService dbCallbackExecutorService; | 175 | protected DbCallbackExecutorService dbCallbackExecutorService; |
180 | 176 | ||
181 | - protected ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId, | ||
182 | - EdgeId edgeId, | ||
183 | - EdgeEventType type, | ||
184 | - EdgeEventActionType action, | ||
185 | - EntityId entityId, | ||
186 | - JsonNode body) { | 177 | + protected void saveEdgeEvent(TenantId tenantId, |
178 | + EdgeId edgeId, | ||
179 | + EdgeEventType type, | ||
180 | + EdgeEventActionType action, | ||
181 | + EntityId entityId, | ||
182 | + JsonNode body) { | ||
187 | log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " + | 183 | log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " + |
188 | "action [{}], entityId [{}], body [{}]", | 184 | "action [{}], entityId [{}], body [{}]", |
189 | tenantId, edgeId, type, action, entityId, body); | 185 | tenantId, edgeId, type, action, entityId, body); |
@@ -197,19 +193,8 @@ public abstract class BaseEdgeProcessor { | @@ -197,19 +193,8 @@ public abstract class BaseEdgeProcessor { | ||
197 | edgeEvent.setEntityId(entityId.getId()); | 193 | edgeEvent.setEntityId(entityId.getId()); |
198 | } | 194 | } |
199 | edgeEvent.setBody(body); | 195 | edgeEvent.setBody(body); |
200 | - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent); | ||
201 | - Futures.addCallback(future, new FutureCallback<EdgeEvent>() { | ||
202 | - @Override | ||
203 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
204 | - tbClusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
205 | - } | ||
206 | - | ||
207 | - @Override | ||
208 | - public void onFailure(Throwable t) { | ||
209 | - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t); | ||
210 | - } | ||
211 | - }, dbCallbackExecutorService); | ||
212 | - return future; | 196 | + edgeEventService.save(edgeEvent); |
197 | + tbClusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
213 | } | 198 | } |
214 | 199 | ||
215 | protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) { | 200 | protected CustomerId getCustomerIdIfEdgeAssignedToCustomer(HasCustomerId hasCustomerIdEntity, Edge edge) { |
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java
@@ -18,7 +18,6 @@ package org.thingsboard.server.service.edge.rpc.processor; | @@ -18,7 +18,6 @@ package org.thingsboard.server.service.edge.rpc.processor; | ||
18 | import com.datastax.oss.driver.api.core.uuid.Uuids; | 18 | import com.datastax.oss.driver.api.core.uuid.Uuids; |
19 | import com.fasterxml.jackson.core.JsonProcessingException; | 19 | import com.fasterxml.jackson.core.JsonProcessingException; |
20 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
21 | -import com.google.common.util.concurrent.FutureCallback; | ||
22 | import com.google.common.util.concurrent.Futures; | 21 | import com.google.common.util.concurrent.Futures; |
23 | import com.google.common.util.concurrent.ListenableFuture; | 22 | import com.google.common.util.concurrent.ListenableFuture; |
24 | import com.google.common.util.concurrent.SettableFuture; | 23 | import com.google.common.util.concurrent.SettableFuture; |
@@ -27,7 +26,7 @@ import org.apache.commons.lang3.RandomStringUtils; | @@ -27,7 +26,7 @@ import org.apache.commons.lang3.RandomStringUtils; | ||
27 | import org.apache.commons.lang3.StringUtils; | 26 | import org.apache.commons.lang3.StringUtils; |
28 | import org.springframework.stereotype.Component; | 27 | import org.springframework.stereotype.Component; |
29 | import org.thingsboard.common.util.JacksonUtil; | 28 | import org.thingsboard.common.util.JacksonUtil; |
30 | -import org.thingsboard.rule.engine.api.RpcError; | 29 | +import org.thingsboard.server.common.data.rpc.RpcError; |
31 | import org.thingsboard.server.common.data.Customer; | 30 | import org.thingsboard.server.common.data.Customer; |
32 | import org.thingsboard.server.common.data.DataConstants; | 31 | import org.thingsboard.server.common.data.DataConstants; |
33 | import org.thingsboard.server.common.data.Device; | 32 | import org.thingsboard.server.common.data.Device; |
@@ -60,7 +59,7 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | @@ -60,7 +59,7 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; | ||
60 | import org.thingsboard.server.queue.TbQueueCallback; | 59 | import org.thingsboard.server.queue.TbQueueCallback; |
61 | import org.thingsboard.server.queue.TbQueueMsgMetadata; | 60 | import org.thingsboard.server.queue.TbQueueMsgMetadata; |
62 | import org.thingsboard.server.queue.util.TbCoreComponent; | 61 | import org.thingsboard.server.queue.util.TbCoreComponent; |
63 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 62 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; |
64 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; | 63 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; |
65 | 64 | ||
66 | import java.util.UUID; | 65 | import java.util.UUID; |
@@ -105,19 +104,8 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | @@ -105,19 +104,8 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | ||
105 | Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); | 104 | Device newDevice = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); |
106 | ObjectNode body = mapper.createObjectNode(); | 105 | ObjectNode body = mapper.createObjectNode(); |
107 | body.put("conflictName", deviceName); | 106 | body.put("conflictName", deviceName); |
108 | - ListenableFuture<EdgeEvent> future = | ||
109 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body); | ||
110 | - Futures.addCallback(future, new FutureCallback<>() { | ||
111 | - @Override | ||
112 | - public void onSuccess(EdgeEvent edgeEvent) { | ||
113 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null); | ||
114 | - } | ||
115 | - | ||
116 | - @Override | ||
117 | - public void onFailure(Throwable t) { | ||
118 | - log.error("[{}] Failed to save ENTITY_MERGE_REQUEST edge event [{}][{}]", tenantId, deviceUpdateMsg, edge.getId(), t); | ||
119 | - } | ||
120 | - }, dbCallbackExecutorService); | 107 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, newDevice.getId(), body); |
108 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, newDevice.getId(), null); | ||
121 | } | 109 | } |
122 | } while (pageData != null && pageData.hasNext()); | 110 | } while (pageData != null && pageData.hasNext()); |
123 | } else { | 111 | } else { |
@@ -155,7 +143,9 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | @@ -155,7 +143,9 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | ||
155 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, device.getId()); | 143 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, device.getId()); |
156 | deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType())); | 144 | deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType())); |
157 | deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId()); | 145 | deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId()); |
158 | - deviceCredentials.setCredentialsValue(deviceCredentialsUpdateMsg.getCredentialsValue()); | 146 | + if (deviceCredentialsUpdateMsg.hasCredentialsValue()) { |
147 | + deviceCredentials.setCredentialsValue(deviceCredentialsUpdateMsg.getCredentialsValue().getValue()); | ||
148 | + } | ||
159 | deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials); | 149 | deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials); |
160 | } catch (Exception e) { | 150 | } catch (Exception e) { |
161 | log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]", device.getName(), deviceCredentialsUpdateMsg, e); | 151 | log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]", device.getName(), deviceCredentialsUpdateMsg, e); |
@@ -173,14 +163,20 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | @@ -173,14 +163,20 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | ||
173 | if (device != null) { | 163 | if (device != null) { |
174 | device.setName(deviceUpdateMsg.getName()); | 164 | device.setName(deviceUpdateMsg.getName()); |
175 | device.setType(deviceUpdateMsg.getType()); | 165 | device.setType(deviceUpdateMsg.getType()); |
176 | - device.setLabel(deviceUpdateMsg.getLabel()); | ||
177 | - device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | ||
178 | - if (deviceUpdateMsg.getDeviceProfileIdMSB() != 0 && deviceUpdateMsg.getDeviceProfileIdLSB() != 0) { | 166 | + if (deviceUpdateMsg.hasLabel()) { |
167 | + device.setLabel(deviceUpdateMsg.getLabel().getValue()); | ||
168 | + } | ||
169 | + if (deviceUpdateMsg.hasAdditionalInfo()) { | ||
170 | + device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo().getValue())); | ||
171 | + } | ||
172 | + if (deviceUpdateMsg.hasDeviceProfileIdMSB() && deviceUpdateMsg.hasDeviceProfileIdLSB()) { | ||
179 | DeviceProfileId deviceProfileId = new DeviceProfileId( | 173 | DeviceProfileId deviceProfileId = new DeviceProfileId( |
180 | - new UUID(deviceUpdateMsg.getDeviceProfileIdMSB(), deviceUpdateMsg.getDeviceProfileIdLSB())); | 174 | + new UUID(deviceUpdateMsg.getDeviceProfileIdMSB().getValue(), |
175 | + deviceUpdateMsg.getDeviceProfileIdLSB().getValue())); | ||
181 | device.setDeviceProfileId(deviceProfileId); | 176 | device.setDeviceProfileId(deviceProfileId); |
182 | } | 177 | } |
183 | - deviceService.saveDevice(device); | 178 | + Device savedDevice = deviceService.saveDevice(device); |
179 | + tbClusterService.onDeviceUpdated(savedDevice, device); | ||
184 | saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | 180 | saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); |
185 | } else { | 181 | } else { |
186 | log.warn("[{}] can't find device [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId()); | 182 | log.warn("[{}] can't find device [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId()); |
@@ -206,22 +202,26 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | @@ -206,22 +202,26 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { | ||
206 | device.setCustomerId(getCustomerId(edge)); | 202 | device.setCustomerId(getCustomerId(edge)); |
207 | device.setName(deviceName); | 203 | device.setName(deviceName); |
208 | device.setType(deviceUpdateMsg.getType()); | 204 | device.setType(deviceUpdateMsg.getType()); |
209 | - device.setLabel(deviceUpdateMsg.getLabel()); | ||
210 | - device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | ||
211 | - if (deviceUpdateMsg.getDeviceProfileIdMSB() != 0 && deviceUpdateMsg.getDeviceProfileIdLSB() != 0) { | 205 | + if (deviceUpdateMsg.hasLabel()) { |
206 | + device.setLabel(deviceUpdateMsg.getLabel().getValue()); | ||
207 | + } | ||
208 | + if (deviceUpdateMsg.hasAdditionalInfo()) { | ||
209 | + device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo().getValue())); | ||
210 | + } | ||
211 | + if (deviceUpdateMsg.hasDeviceProfileIdMSB() && deviceUpdateMsg.hasDeviceProfileIdLSB()) { | ||
212 | DeviceProfileId deviceProfileId = new DeviceProfileId( | 212 | DeviceProfileId deviceProfileId = new DeviceProfileId( |
213 | - new UUID(deviceUpdateMsg.getDeviceProfileIdMSB(), deviceUpdateMsg.getDeviceProfileIdLSB())); | 213 | + new UUID(deviceUpdateMsg.getDeviceProfileIdMSB().getValue(), |
214 | + deviceUpdateMsg.getDeviceProfileIdLSB().getValue())); | ||
214 | device.setDeviceProfileId(deviceProfileId); | 215 | device.setDeviceProfileId(deviceProfileId); |
215 | } | 216 | } |
216 | Device savedDevice = deviceService.saveDevice(device, false); | 217 | Device savedDevice = deviceService.saveDevice(device, false); |
218 | + tbClusterService.onDeviceUpdated(savedDevice, device); | ||
217 | if (created) { | 219 | if (created) { |
218 | DeviceCredentials deviceCredentials = new DeviceCredentials(); | 220 | DeviceCredentials deviceCredentials = new DeviceCredentials(); |
219 | deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); | 221 | deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); |
220 | deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); | 222 | deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); |
221 | deviceCredentials.setCredentialsId(org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(20)); | 223 | deviceCredentials.setCredentialsId(org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(20)); |
222 | deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); | 224 | deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); |
223 | - | ||
224 | - deviceStateService.onDeviceAdded(savedDevice); | ||
225 | } | 225 | } |
226 | createRelationFromEdge(tenantId, edge.getId(), device.getId()); | 226 | createRelationFromEdge(tenantId, edge.getId(), device.getId()); |
227 | pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); | 227 | pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); |
@@ -72,7 +72,9 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { | @@ -72,7 +72,9 @@ public class RelationEdgeProcessor extends BaseEdgeProcessor { | ||
72 | entityRelation.setTo(toId); | 72 | entityRelation.setTo(toId); |
73 | 73 | ||
74 | entityRelation.setType(relationUpdateMsg.getType()); | 74 | entityRelation.setType(relationUpdateMsg.getType()); |
75 | - entityRelation.setTypeGroup(RelationTypeGroup.valueOf(relationUpdateMsg.getTypeGroup())); | 75 | + if (relationUpdateMsg.hasTypeGroup()) { |
76 | + entityRelation.setTypeGroup(RelationTypeGroup.valueOf(relationUpdateMsg.getTypeGroup().getValue())); | ||
77 | + } | ||
76 | entityRelation.setAdditionalInfo(mapper.readTree(relationUpdateMsg.getAdditionalInfo())); | 78 | entityRelation.setAdditionalInfo(mapper.readTree(relationUpdateMsg.getAdditionalInfo())); |
77 | switch (relationUpdateMsg.getMsgType()) { | 79 | switch (relationUpdateMsg.getMsgType()) { |
78 | case ENTITY_CREATED_RPC_MESSAGE: | 80 | case ENTITY_CREATED_RPC_MESSAGE: |
@@ -73,7 +73,7 @@ import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; | @@ -73,7 +73,7 @@ import org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg; | ||
73 | import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; | 73 | import org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg; |
74 | import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; | 74 | import org.thingsboard.server.service.edge.rpc.EdgeEventUtils; |
75 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 75 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
76 | -import org.thingsboard.server.service.queue.TbClusterService; | 76 | +import org.thingsboard.server.cluster.TbClusterService; |
77 | 77 | ||
78 | import java.util.ArrayList; | 78 | import java.util.ArrayList; |
79 | import java.util.HashMap; | 79 | import java.util.HashMap; |
@@ -122,26 +122,13 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -122,26 +122,13 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
122 | @Override | 122 | @Override |
123 | public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { | 123 | public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { |
124 | log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg); | 124 | log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg); |
125 | - SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
126 | if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { | 125 | if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { |
127 | RuleChainId ruleChainId = | 126 | RuleChainId ruleChainId = |
128 | new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); | 127 | new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); |
129 | - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), | 128 | + saveEdgeEvent(tenantId, edge.getId(), |
130 | EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); | 129 | EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); |
131 | - Futures.addCallback(future, new FutureCallback<EdgeEvent>() { | ||
132 | - @Override | ||
133 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
134 | - futureToSet.set(null); | ||
135 | - } | ||
136 | - | ||
137 | - @Override | ||
138 | - public void onFailure(Throwable t) { | ||
139 | - log.error("Can't save edge event [{}]", ruleChainMetadataRequestMsg, t); | ||
140 | - futureToSet.setException(t); | ||
141 | - } | ||
142 | - }, dbCallbackExecutorService); | ||
143 | } | 130 | } |
144 | - return futureToSet; | 131 | + return Futures.immediateFuture(null); |
145 | } | 132 | } |
146 | 133 | ||
147 | @Override | 134 | @Override |
@@ -154,8 +141,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -154,8 +141,8 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
154 | if (type != null) { | 141 | if (type != null) { |
155 | SettableFuture<Void> futureToSet = SettableFuture.create(); | 142 | SettableFuture<Void> futureToSet = SettableFuture.create(); |
156 | String scope = attributesRequestMsg.getScope(); | 143 | String scope = attributesRequestMsg.getScope(); |
157 | - ListenableFuture<List<AttributeKvEntry>> ssAttrFuture = attributesService.findAll(tenantId, entityId, scope); | ||
158 | - Futures.addCallback(ssAttrFuture, new FutureCallback<List<AttributeKvEntry>>() { | 144 | + ListenableFuture<List<AttributeKvEntry>> findAttrFuture = attributesService.findAll(tenantId, entityId, scope); |
145 | + Futures.addCallback(findAttrFuture, new FutureCallback<List<AttributeKvEntry>>() { | ||
159 | @Override | 146 | @Override |
160 | public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) { | 147 | public void onSuccess(@Nullable List<AttributeKvEntry> ssAttributes) { |
161 | if (ssAttributes != null && !ssAttributes.isEmpty()) { | 148 | if (ssAttributes != null && !ssAttributes.isEmpty()) { |
@@ -184,8 +171,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -184,8 +171,9 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
184 | entityId, | 171 | entityId, |
185 | body); | 172 | body); |
186 | } catch (Exception e) { | 173 | } catch (Exception e) { |
187 | - log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e); | ||
188 | - throw new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e); | 174 | + log.error("[{}] Failed to save attribute updates to the edge", edge.getName(), e); |
175 | + futureToSet.setException(new RuntimeException("[" + edge.getName() + "] Failed to send attribute updates to the edge", e)); | ||
176 | + return; | ||
189 | } | 177 | } |
190 | } else { | 178 | } else { |
191 | log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId, | 179 | log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId, |
@@ -198,7 +186,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -198,7 +186,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
198 | 186 | ||
199 | @Override | 187 | @Override |
200 | public void onFailure(Throwable t) { | 188 | public void onFailure(Throwable t) { |
201 | - log.error("Can't save attributes [{}]", attributesRequestMsg, t); | 189 | + log.error("Can't find attributes [{}]", attributesRequestMsg, t); |
202 | futureToSet.setException(t); | 190 | futureToSet.setException(t); |
203 | } | 191 | } |
204 | }, dbCallbackExecutorService); | 192 | }, dbCallbackExecutorService); |
@@ -273,82 +261,39 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -273,82 +261,39 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
273 | @Override | 261 | @Override |
274 | public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) { | 262 | public ListenableFuture<Void> processDeviceCredentialsRequestMsg(TenantId tenantId, Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) { |
275 | log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg); | 263 | log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), deviceCredentialsRequestMsg); |
276 | - SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
277 | if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { | 264 | if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { |
278 | DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); | 265 | DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); |
279 | - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, | 266 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, |
280 | EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); | 267 | EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); |
281 | - Futures.addCallback(future, new FutureCallback<EdgeEvent>() { | ||
282 | - @Override | ||
283 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
284 | - futureToSet.set(null); | ||
285 | - } | ||
286 | - | ||
287 | - @Override | ||
288 | - public void onFailure(Throwable t) { | ||
289 | - log.error("Can't save edge event [{}]", deviceCredentialsRequestMsg, t); | ||
290 | - futureToSet.setException(t); | ||
291 | - } | ||
292 | - }, dbCallbackExecutorService); | ||
293 | } | 268 | } |
294 | - return futureToSet; | 269 | + return Futures.immediateFuture(null); |
295 | } | 270 | } |
296 | 271 | ||
297 | @Override | 272 | @Override |
298 | public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) { | 273 | public ListenableFuture<Void> processUserCredentialsRequestMsg(TenantId tenantId, Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) { |
299 | log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg); | 274 | log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", tenantId, edge.getName(), userCredentialsRequestMsg); |
300 | - SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
301 | if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { | 275 | if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { |
302 | UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); | 276 | UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); |
303 | - ListenableFuture<EdgeEvent> future = saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, | 277 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.USER, |
304 | EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); | 278 | EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); |
305 | - Futures.addCallback(future, new FutureCallback<>() { | ||
306 | - @Override | ||
307 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
308 | - futureToSet.set(null); | ||
309 | - } | ||
310 | - | ||
311 | - @Override | ||
312 | - public void onFailure(Throwable t) { | ||
313 | - log.error("Can't save edge event [{}]", userCredentialsRequestMsg, t); | ||
314 | - futureToSet.setException(t); | ||
315 | - } | ||
316 | - }, dbCallbackExecutorService); | ||
317 | } | 279 | } |
318 | - return futureToSet; | 280 | + return Futures.immediateFuture(null); |
319 | } | 281 | } |
320 | 282 | ||
321 | @Override | 283 | @Override |
322 | public ListenableFuture<Void> processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) { | 284 | public ListenableFuture<Void> processDeviceProfileDevicesRequestMsg(TenantId tenantId, Edge edge, DeviceProfileDevicesRequestMsg deviceProfileDevicesRequestMsg) { |
323 | log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg); | 285 | log.trace("[{}] processDeviceProfileDevicesRequestMsg [{}][{}]", tenantId, edge.getName(), deviceProfileDevicesRequestMsg); |
324 | - SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
325 | if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) { | 286 | if (deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB() != 0 && deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB() != 0) { |
326 | DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB())); | 287 | DeviceProfileId deviceProfileId = new DeviceProfileId(new UUID(deviceProfileDevicesRequestMsg.getDeviceProfileIdMSB(), deviceProfileDevicesRequestMsg.getDeviceProfileIdLSB())); |
327 | DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId); | 288 | DeviceProfile deviceProfileById = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId); |
328 | - List<ListenableFuture<EdgeEvent>> futures; | ||
329 | if (deviceProfileById != null) { | 289 | if (deviceProfileById != null) { |
330 | - futures = syncDevices(tenantId, edge, deviceProfileById.getName()); | ||
331 | - } else { | ||
332 | - futures = new ArrayList<>(); | 290 | + syncDevices(tenantId, edge, deviceProfileById.getName()); |
333 | } | 291 | } |
334 | - Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() { | ||
335 | - @Override | ||
336 | - public void onSuccess(@Nullable List<EdgeEvent> result) { | ||
337 | - futureToSet.set(null); | ||
338 | - } | ||
339 | - | ||
340 | - @Override | ||
341 | - public void onFailure(Throwable t) { | ||
342 | - log.error("Can't sync devices by device profile [{}]", deviceProfileDevicesRequestMsg, t); | ||
343 | - futureToSet.setException(t); | ||
344 | - } | ||
345 | - }, dbCallbackExecutorService); | ||
346 | } | 292 | } |
347 | - return futureToSet; | 293 | + return Futures.immediateFuture(null); |
348 | } | 294 | } |
349 | 295 | ||
350 | - private List<ListenableFuture<EdgeEvent>> syncDevices(TenantId tenantId, Edge edge, String deviceType) { | ||
351 | - List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>(); | 296 | + private void syncDevices(TenantId tenantId, Edge edge, String deviceType) { |
352 | log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType); | 297 | log.trace("[{}] syncDevices [{}][{}]", tenantId, edge.getName(), deviceType); |
353 | try { | 298 | try { |
354 | PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); | 299 | PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); |
@@ -358,7 +303,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -358,7 +303,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
358 | if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { | 303 | if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { |
359 | log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); | 304 | log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); |
360 | for (Device device : pageData.getData()) { | 305 | for (Device device : pageData.getData()) { |
361 | - futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null)); | 306 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null); |
362 | } | 307 | } |
363 | if (pageData.hasNext()) { | 308 | if (pageData.hasNext()) { |
364 | pageLink = pageLink.nextPageLink(); | 309 | pageLink = pageLink.nextPageLink(); |
@@ -368,40 +313,25 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -368,40 +313,25 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
368 | } catch (Exception e) { | 313 | } catch (Exception e) { |
369 | log.error("Exception during loading edge device(s) on sync!", e); | 314 | log.error("Exception during loading edge device(s) on sync!", e); |
370 | } | 315 | } |
371 | - return futures; | ||
372 | } | 316 | } |
373 | 317 | ||
374 | @Override | 318 | @Override |
375 | public ListenableFuture<Void> processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge, | 319 | public ListenableFuture<Void> processWidgetBundleTypesRequestMsg(TenantId tenantId, Edge edge, |
376 | WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) { | 320 | WidgetBundleTypesRequestMsg widgetBundleTypesRequestMsg) { |
377 | log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg); | 321 | log.trace("[{}] processWidgetBundleTypesRequestMsg [{}][{}]", tenantId, edge.getName(), widgetBundleTypesRequestMsg); |
378 | - SettableFuture<Void> futureToSet = SettableFuture.create(); | ||
379 | if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) { | 322 | if (widgetBundleTypesRequestMsg.getWidgetBundleIdMSB() != 0 && widgetBundleTypesRequestMsg.getWidgetBundleIdLSB() != 0) { |
380 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB())); | 323 | WidgetsBundleId widgetsBundleId = new WidgetsBundleId(new UUID(widgetBundleTypesRequestMsg.getWidgetBundleIdMSB(), widgetBundleTypesRequestMsg.getWidgetBundleIdLSB())); |
381 | WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId); | 324 | WidgetsBundle widgetsBundleById = widgetsBundleService.findWidgetsBundleById(tenantId, widgetsBundleId); |
382 | - List<ListenableFuture<EdgeEvent>> futures = new ArrayList<>(); | ||
383 | if (widgetsBundleById != null) { | 325 | if (widgetsBundleById != null) { |
384 | List<WidgetType> widgetTypesToPush = | 326 | List<WidgetType> widgetTypesToPush = |
385 | widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias()); | 327 | widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundleById.getTenantId(), widgetsBundleById.getAlias()); |
386 | 328 | ||
387 | for (WidgetType widgetType : widgetTypesToPush) { | 329 | for (WidgetType widgetType : widgetTypesToPush) { |
388 | - futures.add(saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null)); | 330 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null); |
389 | } | 331 | } |
390 | } | 332 | } |
391 | - Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() { | ||
392 | - @Override | ||
393 | - public void onSuccess(@Nullable List<EdgeEvent> result) { | ||
394 | - futureToSet.set(null); | ||
395 | - } | ||
396 | - | ||
397 | - @Override | ||
398 | - public void onFailure(Throwable t) { | ||
399 | - log.error("Can't sync widget types by widget bundle [{}]", widgetBundleTypesRequestMsg, t); | ||
400 | - futureToSet.setException(t); | ||
401 | - } | ||
402 | - }, dbCallbackExecutorService); | ||
403 | } | 333 | } |
404 | - return futureToSet; | 334 | + return Futures.immediateFuture(null); |
405 | } | 335 | } |
406 | 336 | ||
407 | @Override | 337 | @Override |
@@ -416,9 +346,12 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -416,9 +346,12 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
416 | public void onSuccess(@Nullable List<EntityView> entityViews) { | 346 | public void onSuccess(@Nullable List<EntityView> entityViews) { |
417 | try { | 347 | try { |
418 | if (entityViews != null && !entityViews.isEmpty()) { | 348 | if (entityViews != null && !entityViews.isEmpty()) { |
349 | + List<ListenableFuture<Boolean>> futures = new ArrayList<>(); | ||
419 | for (EntityView entityView : entityViews) { | 350 | for (EntityView entityView : entityViews) { |
420 | - Futures.addCallback(relationService.checkRelation(tenantId, edge.getId(), entityView.getId(), | ||
421 | - EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE), new FutureCallback<>() { | 351 | + ListenableFuture<Boolean> future = relationService.checkRelation(tenantId, edge.getId(), entityView.getId(), |
352 | + EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); | ||
353 | + futures.add(future); | ||
354 | + Futures.addCallback(future, new FutureCallback<>() { | ||
422 | @Override | 355 | @Override |
423 | public void onSuccess(@Nullable Boolean result) { | 356 | public void onSuccess(@Nullable Boolean result) { |
424 | if (Boolean.TRUE.equals(result)) { | 357 | if (Boolean.TRUE.equals(result)) { |
@@ -426,16 +359,27 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -426,16 +359,27 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
426 | EdgeEventActionType.ADDED, entityView.getId(), null); | 359 | EdgeEventActionType.ADDED, entityView.getId(), null); |
427 | } | 360 | } |
428 | } | 361 | } |
429 | - | ||
430 | @Override | 362 | @Override |
431 | public void onFailure(Throwable t) { | 363 | public void onFailure(Throwable t) { |
432 | - log.error("Exception during loading relation [{}] to edge on sync!", t, t); | ||
433 | - futureToSet.setException(t); | 364 | + // Do nothing - error handles in allAsList |
434 | } | 365 | } |
435 | }, dbCallbackExecutorService); | 366 | }, dbCallbackExecutorService); |
436 | } | 367 | } |
368 | + Futures.addCallback(Futures.allAsList(futures), new FutureCallback<>() { | ||
369 | + @Override | ||
370 | + public void onSuccess(@Nullable List<Boolean> result) { | ||
371 | + futureToSet.set(null); | ||
372 | + } | ||
373 | + | ||
374 | + @Override | ||
375 | + public void onFailure(Throwable t) { | ||
376 | + log.error("Exception during loading relation [{}] to edge on sync!", t, t); | ||
377 | + futureToSet.setException(t); | ||
378 | + } | ||
379 | + }, dbCallbackExecutorService); | ||
380 | + } else { | ||
381 | + futureToSet.set(null); | ||
437 | } | 382 | } |
438 | - futureToSet.set(null); | ||
439 | } catch (Exception e) { | 383 | } catch (Exception e) { |
440 | log.error("Exception during loading relation(s) to edge on sync!", e); | 384 | log.error("Exception during loading relation(s) to edge on sync!", e); |
441 | futureToSet.setException(e); | 385 | futureToSet.setException(e); |
@@ -451,30 +395,19 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | @@ -451,30 +395,19 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { | ||
451 | return futureToSet; | 395 | return futureToSet; |
452 | } | 396 | } |
453 | 397 | ||
454 | - private ListenableFuture<EdgeEvent> saveEdgeEvent(TenantId tenantId, | ||
455 | - EdgeId edgeId, | ||
456 | - EdgeEventType type, | ||
457 | - EdgeEventActionType action, | ||
458 | - EntityId entityId, | ||
459 | - JsonNode body) { | 398 | + private void saveEdgeEvent(TenantId tenantId, |
399 | + EdgeId edgeId, | ||
400 | + EdgeEventType type, | ||
401 | + EdgeEventActionType action, | ||
402 | + EntityId entityId, | ||
403 | + JsonNode body) { | ||
460 | log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", | 404 | log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", |
461 | tenantId, edgeId, type, action, entityId, body); | 405 | tenantId, edgeId, type, action, entityId, body); |
462 | 406 | ||
463 | EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); | 407 | EdgeEvent edgeEvent = EdgeEventUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); |
464 | 408 | ||
465 | - ListenableFuture<EdgeEvent> future = edgeEventService.saveAsync(edgeEvent); | ||
466 | - Futures.addCallback(future, new FutureCallback<>() { | ||
467 | - @Override | ||
468 | - public void onSuccess(@Nullable EdgeEvent result) { | ||
469 | - tbClusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
470 | - } | ||
471 | - | ||
472 | - @Override | ||
473 | - public void onFailure(Throwable t) { | ||
474 | - log.warn("[{}] Can't save edge event [{}] for edge [{}]", tenantId.getId(), edgeEvent, edgeId.getId(), t); | ||
475 | - } | ||
476 | - }, dbCallbackExecutorService); | ||
477 | - return future; | 409 | + edgeEventService.save(edgeEvent); |
410 | + tbClusterService.onEdgeEventUpdate(tenantId, edgeId); | ||
478 | } | 411 | } |
479 | 412 | ||
480 | } | 413 | } |
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
@@ -215,6 +215,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | @@ -215,6 +215,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | ||
215 | node.put("password", ""); | 215 | node.put("password", ""); |
216 | node.put("tlsVersion", "TLSv1.2");//NOSONAR, key used to identify password field (not password value itself) | 216 | node.put("tlsVersion", "TLSv1.2");//NOSONAR, key used to identify password field (not password value itself) |
217 | node.put("enableProxy", false); | 217 | node.put("enableProxy", false); |
218 | + node.put("showChangePassword", false); | ||
218 | mailSettings.setJsonValue(node); | 219 | mailSettings.setJsonValue(node); |
219 | adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, mailSettings); | 220 | adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, mailSettings); |
220 | } | 221 | } |
@@ -480,6 +481,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | @@ -480,6 +481,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | ||
480 | device.setAdditionalInfo(additionalInfo); | 481 | device.setAdditionalInfo(additionalInfo); |
481 | } | 482 | } |
482 | device = deviceService.saveDevice(device); | 483 | device = deviceService.saveDevice(device); |
484 | + //TODO: No access to cluster service, so we should manually update the status of device. | ||
483 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, device.getId()); | 485 | DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, device.getId()); |
484 | deviceCredentials.setCredentialsId(accessToken); | 486 | deviceCredentials.setCredentialsId(accessToken); |
485 | deviceCredentialsService.updateDeviceCredentials(TenantId.SYS_TENANT_ID, deviceCredentials); | 487 | deviceCredentialsService.updateDeviceCredentials(TenantId.SYS_TENANT_ID, deviceCredentials); |
@@ -17,6 +17,7 @@ package org.thingsboard.server.service.ota; | @@ -17,6 +17,7 @@ package org.thingsboard.server.service.ota; | ||
17 | 17 | ||
18 | import com.google.common.util.concurrent.FutureCallback; | 18 | import com.google.common.util.concurrent.FutureCallback; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | +import org.springframework.context.annotation.Lazy; | ||
20 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
21 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; | 22 | import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; |
22 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; | 23 | import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; |
@@ -49,7 +50,7 @@ import org.thingsboard.server.queue.TbQueueProducer; | @@ -49,7 +50,7 @@ import org.thingsboard.server.queue.TbQueueProducer; | ||
49 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 50 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
50 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; | 51 | import org.thingsboard.server.queue.provider.TbCoreQueueFactory; |
51 | import org.thingsboard.server.queue.util.TbCoreComponent; | 52 | import org.thingsboard.server.queue.util.TbCoreComponent; |
52 | -import org.thingsboard.server.service.queue.TbClusterService; | 53 | +import org.thingsboard.server.cluster.TbClusterService; |
53 | 54 | ||
54 | import javax.annotation.Nullable; | 55 | import javax.annotation.Nullable; |
55 | import java.util.ArrayList; | 56 | import java.util.ArrayList; |
@@ -87,10 +88,11 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService { | @@ -87,10 +88,11 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService { | ||
87 | private final RuleEngineTelemetryService telemetryService; | 88 | private final RuleEngineTelemetryService telemetryService; |
88 | private final TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> otaPackageStateMsgProducer; | 89 | private final TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> otaPackageStateMsgProducer; |
89 | 90 | ||
90 | - public DefaultOtaPackageStateService(TbClusterService tbClusterService, OtaPackageService otaPackageService, | 91 | + public DefaultOtaPackageStateService(@Lazy TbClusterService tbClusterService, |
92 | + OtaPackageService otaPackageService, | ||
91 | DeviceService deviceService, | 93 | DeviceService deviceService, |
92 | DeviceProfileService deviceProfileService, | 94 | DeviceProfileService deviceProfileService, |
93 | - RuleEngineTelemetryService telemetryService, | 95 | + @Lazy RuleEngineTelemetryService telemetryService, |
94 | TbCoreQueueFactory coreQueueFactory) { | 96 | TbCoreQueueFactory coreQueueFactory) { |
95 | this.tbClusterService = tbClusterService; | 97 | this.tbClusterService = tbClusterService; |
96 | this.otaPackageService = otaPackageService; | 98 | this.otaPackageService = otaPackageService; |
@@ -16,11 +16,17 @@ | @@ -16,11 +16,17 @@ | ||
16 | package org.thingsboard.server.service.queue; | 16 | package org.thingsboard.server.service.queue; |
17 | 17 | ||
18 | import com.google.protobuf.ByteString; | 18 | import com.google.protobuf.ByteString; |
19 | +import lombok.RequiredArgsConstructor; | ||
19 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
20 | import org.springframework.beans.factory.annotation.Value; | 21 | import org.springframework.beans.factory.annotation.Value; |
21 | import org.springframework.scheduling.annotation.Scheduled; | 22 | import org.springframework.scheduling.annotation.Scheduled; |
22 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
23 | -import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | 24 | +import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; |
25 | +import org.thingsboard.server.cluster.TbClusterService; | ||
26 | +import org.thingsboard.server.common.data.EdgeUtils; | ||
27 | +import org.thingsboard.server.common.data.edge.EdgeEventActionType; | ||
28 | +import org.thingsboard.server.common.data.edge.EdgeEventType; | ||
29 | +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; | ||
24 | import org.thingsboard.server.common.data.ApiUsageState; | 30 | import org.thingsboard.server.common.data.ApiUsageState; |
25 | import org.thingsboard.server.common.data.Device; | 31 | import org.thingsboard.server.common.data.Device; |
26 | import org.thingsboard.server.common.data.DeviceProfile; | 32 | import org.thingsboard.server.common.data.DeviceProfile; |
@@ -29,7 +35,6 @@ import org.thingsboard.server.common.data.HasName; | @@ -29,7 +35,6 @@ import org.thingsboard.server.common.data.HasName; | ||
29 | import org.thingsboard.server.common.data.TbResource; | 35 | import org.thingsboard.server.common.data.TbResource; |
30 | import org.thingsboard.server.common.data.Tenant; | 36 | import org.thingsboard.server.common.data.Tenant; |
31 | import org.thingsboard.server.common.data.TenantProfile; | 37 | import org.thingsboard.server.common.data.TenantProfile; |
32 | -import org.thingsboard.server.common.data.id.CustomerId; | ||
33 | import org.thingsboard.server.common.data.id.DeviceId; | 38 | import org.thingsboard.server.common.data.id.DeviceId; |
34 | import org.thingsboard.server.common.data.id.DeviceProfileId; | 39 | import org.thingsboard.server.common.data.id.DeviceProfileId; |
35 | import org.thingsboard.server.common.data.id.EdgeId; | 40 | import org.thingsboard.server.common.data.id.EdgeId; |
@@ -56,8 +61,9 @@ import org.thingsboard.server.queue.common.MultipleTbQueueCallbackWrapper; | @@ -56,8 +61,9 @@ import org.thingsboard.server.queue.common.MultipleTbQueueCallbackWrapper; | ||
56 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; | 61 | import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
57 | import org.thingsboard.server.queue.discovery.PartitionService; | 62 | import org.thingsboard.server.queue.discovery.PartitionService; |
58 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 63 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
64 | +import org.thingsboard.server.service.ota.OtaPackageStateService; | ||
59 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 65 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
60 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 66 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; |
61 | 67 | ||
62 | import java.util.HashSet; | 68 | import java.util.HashSet; |
63 | import java.util.Set; | 69 | import java.util.Set; |
@@ -66,10 +72,13 @@ import java.util.concurrent.atomic.AtomicInteger; | @@ -66,10 +72,13 @@ import java.util.concurrent.atomic.AtomicInteger; | ||
66 | 72 | ||
67 | @Service | 73 | @Service |
68 | @Slf4j | 74 | @Slf4j |
75 | +@RequiredArgsConstructor | ||
69 | public class DefaultTbClusterService implements TbClusterService { | 76 | public class DefaultTbClusterService implements TbClusterService { |
70 | 77 | ||
71 | @Value("${cluster.stats.enabled:false}") | 78 | @Value("${cluster.stats.enabled:false}") |
72 | private boolean statsEnabled; | 79 | private boolean statsEnabled; |
80 | + @Value("${edges.enabled}") | ||
81 | + protected boolean edgesEnabled; | ||
73 | 82 | ||
74 | private final AtomicInteger toCoreMsgs = new AtomicInteger(0); | 83 | private final AtomicInteger toCoreMsgs = new AtomicInteger(0); |
75 | private final AtomicInteger toCoreNfs = new AtomicInteger(0); | 84 | private final AtomicInteger toCoreNfs = new AtomicInteger(0); |
@@ -81,13 +90,7 @@ public class DefaultTbClusterService implements TbClusterService { | @@ -81,13 +90,7 @@ public class DefaultTbClusterService implements TbClusterService { | ||
81 | private final PartitionService partitionService; | 90 | private final PartitionService partitionService; |
82 | private final DataDecodingEncodingService encodingService; | 91 | private final DataDecodingEncodingService encodingService; |
83 | private final TbDeviceProfileCache deviceProfileCache; | 92 | private final TbDeviceProfileCache deviceProfileCache; |
84 | - | ||
85 | - public DefaultTbClusterService(TbQueueProducerProvider producerProvider, PartitionService partitionService, DataDecodingEncodingService encodingService, TbDeviceProfileCache deviceProfileCache) { | ||
86 | - this.producerProvider = producerProvider; | ||
87 | - this.partitionService = partitionService; | ||
88 | - this.encodingService = encodingService; | ||
89 | - this.deviceProfileCache = deviceProfileCache; | ||
90 | - } | 93 | + private final OtaPackageStateService otaPackageStateService; |
91 | 94 | ||
92 | @Override | 95 | @Override |
93 | public void pushMsgToCore(TenantId tenantId, EntityId entityId, ToCoreMsg msg, TbQueueCallback callback) { | 96 | public void pushMsgToCore(TenantId tenantId, EntityId entityId, ToCoreMsg msg, TbQueueCallback callback) { |
@@ -200,55 +203,52 @@ public class DefaultTbClusterService implements TbClusterService { | @@ -200,55 +203,52 @@ public class DefaultTbClusterService implements TbClusterService { | ||
200 | } | 203 | } |
201 | 204 | ||
202 | @Override | 205 | @Override |
203 | - public void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state) { | 206 | + public void broadcastEntityStateChangeEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state) { |
204 | log.trace("[{}] Processing {} state change event: {}", tenantId, entityId.getEntityType(), state); | 207 | log.trace("[{}] Processing {} state change event: {}", tenantId, entityId.getEntityType(), state); |
205 | broadcast(new ComponentLifecycleMsg(tenantId, entityId, state)); | 208 | broadcast(new ComponentLifecycleMsg(tenantId, entityId, state)); |
206 | } | 209 | } |
207 | 210 | ||
208 | @Override | 211 | @Override |
209 | public void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback) { | 212 | public void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback) { |
210 | - onEntityChange(deviceProfile.getTenantId(), deviceProfile.getId(), deviceProfile, callback); | 213 | + broadcastEntityChangeToTransport(deviceProfile.getTenantId(), deviceProfile.getId(), deviceProfile, callback); |
211 | } | 214 | } |
212 | 215 | ||
213 | @Override | 216 | @Override |
214 | public void onTenantProfileChange(TenantProfile tenantProfile, TbQueueCallback callback) { | 217 | public void onTenantProfileChange(TenantProfile tenantProfile, TbQueueCallback callback) { |
215 | - onEntityChange(TenantId.SYS_TENANT_ID, tenantProfile.getId(), tenantProfile, callback); | 218 | + broadcastEntityChangeToTransport(TenantId.SYS_TENANT_ID, tenantProfile.getId(), tenantProfile, callback); |
216 | } | 219 | } |
217 | 220 | ||
218 | @Override | 221 | @Override |
219 | public void onTenantChange(Tenant tenant, TbQueueCallback callback) { | 222 | public void onTenantChange(Tenant tenant, TbQueueCallback callback) { |
220 | - onEntityChange(TenantId.SYS_TENANT_ID, tenant.getId(), tenant, callback); | 223 | + broadcastEntityChangeToTransport(TenantId.SYS_TENANT_ID, tenant.getId(), tenant, callback); |
221 | } | 224 | } |
222 | 225 | ||
223 | @Override | 226 | @Override |
224 | public void onApiStateChange(ApiUsageState apiUsageState, TbQueueCallback callback) { | 227 | public void onApiStateChange(ApiUsageState apiUsageState, TbQueueCallback callback) { |
225 | - onEntityChange(apiUsageState.getTenantId(), apiUsageState.getId(), apiUsageState, callback); | 228 | + broadcastEntityChangeToTransport(apiUsageState.getTenantId(), apiUsageState.getId(), apiUsageState, callback); |
226 | broadcast(new ComponentLifecycleMsg(apiUsageState.getTenantId(), apiUsageState.getId(), ComponentLifecycleEvent.UPDATED)); | 229 | broadcast(new ComponentLifecycleMsg(apiUsageState.getTenantId(), apiUsageState.getId(), ComponentLifecycleEvent.UPDATED)); |
227 | } | 230 | } |
228 | 231 | ||
229 | @Override | 232 | @Override |
230 | public void onDeviceProfileDelete(DeviceProfile entity, TbQueueCallback callback) { | 233 | public void onDeviceProfileDelete(DeviceProfile entity, TbQueueCallback callback) { |
231 | - onEntityDelete(entity.getTenantId(), entity.getId(), entity.getName(), callback); | 234 | + broadcastEntityDeleteToTransport(entity.getTenantId(), entity.getId(), entity.getName(), callback); |
232 | } | 235 | } |
233 | 236 | ||
234 | @Override | 237 | @Override |
235 | public void onTenantProfileDelete(TenantProfile entity, TbQueueCallback callback) { | 238 | public void onTenantProfileDelete(TenantProfile entity, TbQueueCallback callback) { |
236 | - onEntityDelete(TenantId.SYS_TENANT_ID, entity.getId(), entity.getName(), callback); | 239 | + broadcastEntityDeleteToTransport(TenantId.SYS_TENANT_ID, entity.getId(), entity.getName(), callback); |
237 | } | 240 | } |
238 | 241 | ||
239 | @Override | 242 | @Override |
240 | public void onTenantDelete(Tenant entity, TbQueueCallback callback) { | 243 | public void onTenantDelete(Tenant entity, TbQueueCallback callback) { |
241 | - onEntityDelete(TenantId.SYS_TENANT_ID, entity.getId(), entity.getName(), callback); | 244 | + broadcastEntityDeleteToTransport(TenantId.SYS_TENANT_ID, entity.getId(), entity.getName(), callback); |
242 | } | 245 | } |
243 | 246 | ||
244 | @Override | 247 | @Override |
245 | - public void onDeviceChange(Device entity, TbQueueCallback callback) { | ||
246 | - onEntityChange(entity.getTenantId(), entity.getId(), entity, callback); | ||
247 | - } | ||
248 | - | ||
249 | - @Override | ||
250 | - public void onDeviceDeleted(Device entity, TbQueueCallback callback) { | ||
251 | - onEntityDelete(entity.getTenantId(), entity.getId(), entity.getName(), callback); | 248 | + public void onDeviceDeleted(Device device, TbQueueCallback callback) { |
249 | + broadcastEntityDeleteToTransport(device.getTenantId(), device.getId(), device.getName(), callback); | ||
250 | + sendDeviceStateServiceEvent(device.getTenantId(), device.getId(), false, false, true); | ||
251 | + broadcastEntityStateChangeEvent(device.getTenantId(), device.getId(), ComponentLifecycleEvent.DELETED); | ||
252 | } | 252 | } |
253 | 253 | ||
254 | @Override | 254 | @Override |
@@ -278,7 +278,7 @@ public class DefaultTbClusterService implements TbClusterService { | @@ -278,7 +278,7 @@ public class DefaultTbClusterService implements TbClusterService { | ||
278 | broadcast(transportMsg, callback); | 278 | broadcast(transportMsg, callback); |
279 | } | 279 | } |
280 | 280 | ||
281 | - public <T> void onEntityChange(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) { | 281 | + public <T> void broadcastEntityChangeToTransport(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) { |
282 | String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName(); | 282 | String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName(); |
283 | log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName); | 283 | log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName); |
284 | TransportProtos.EntityUpdateMsg entityUpdateMsg = TransportProtos.EntityUpdateMsg.newBuilder() | 284 | TransportProtos.EntityUpdateMsg entityUpdateMsg = TransportProtos.EntityUpdateMsg.newBuilder() |
@@ -288,7 +288,7 @@ public class DefaultTbClusterService implements TbClusterService { | @@ -288,7 +288,7 @@ public class DefaultTbClusterService implements TbClusterService { | ||
288 | broadcast(transportMsg, callback); | 288 | broadcast(transportMsg, callback); |
289 | } | 289 | } |
290 | 290 | ||
291 | - private void onEntityDelete(TenantId tenantId, EntityId entityId, String name, TbQueueCallback callback) { | 291 | + private void broadcastEntityDeleteToTransport(TenantId tenantId, EntityId entityId, String name, TbQueueCallback callback) { |
292 | log.trace("[{}][{}][{}] Processing [{}] delete event", tenantId, entityId.getEntityType(), entityId.getId(), name); | 292 | log.trace("[{}][{}][{}] Processing [{}] delete event", tenantId, entityId.getEntityType(), entityId.getId(), name); |
293 | TransportProtos.EntityDeleteMsg entityDeleteMsg = TransportProtos.EntityDeleteMsg.newBuilder() | 293 | TransportProtos.EntityDeleteMsg entityDeleteMsg = TransportProtos.EntityDeleteMsg.newBuilder() |
294 | .setEntityType(entityId.getEntityType().name()) | 294 | .setEntityType(entityId.getEntityType().name()) |
@@ -369,4 +369,72 @@ public class DefaultTbClusterService implements TbClusterService { | @@ -369,4 +369,72 @@ public class DefaultTbClusterService implements TbClusterService { | ||
369 | } | 369 | } |
370 | } | 370 | } |
371 | } | 371 | } |
372 | + | ||
373 | + private void sendDeviceStateServiceEvent(TenantId tenantId, DeviceId deviceId, boolean added, boolean updated, boolean deleted) { | ||
374 | + TransportProtos.DeviceStateServiceMsgProto.Builder builder = TransportProtos.DeviceStateServiceMsgProto.newBuilder(); | ||
375 | + builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); | ||
376 | + builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); | ||
377 | + builder.setDeviceIdMSB(deviceId.getId().getMostSignificantBits()); | ||
378 | + builder.setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()); | ||
379 | + builder.setAdded(added); | ||
380 | + builder.setUpdated(updated); | ||
381 | + builder.setDeleted(deleted); | ||
382 | + TransportProtos.DeviceStateServiceMsgProto msg = builder.build(); | ||
383 | + pushMsgToCore(tenantId, deviceId, TransportProtos.ToCoreMsg.newBuilder().setDeviceStateServiceMsg(msg).build(), null); | ||
384 | + } | ||
385 | + | ||
386 | + @Override | ||
387 | + public void onDeviceUpdated(Device device, Device old) { | ||
388 | + var created = old == null; | ||
389 | + broadcastEntityChangeToTransport(device.getTenantId(), device.getId(), device, null); | ||
390 | + if (old != null && (!device.getName().equals(old.getName()) || !device.getType().equals(old.getType()))) { | ||
391 | + pushMsgToCore(new DeviceNameOrTypeUpdateMsg(device.getTenantId(), device.getId(), device.getName(), device.getType()), null); | ||
392 | + } | ||
393 | + broadcastEntityStateChangeEvent(device.getTenantId(), device.getId(), created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); | ||
394 | + sendDeviceStateServiceEvent(device.getTenantId(), device.getId(), created, !created, false); | ||
395 | + otaPackageStateService.update(device, old); | ||
396 | + if (!created) { | ||
397 | + sendNotificationMsgToEdgeService(device.getTenantId(), null, device.getId(), null, null, EdgeEventActionType.UPDATED); | ||
398 | + } | ||
399 | + } | ||
400 | + | ||
401 | + @Override | ||
402 | + public void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { | ||
403 | + if (!edgesEnabled) { | ||
404 | + return; | ||
405 | + } | ||
406 | + if (type == null) { | ||
407 | + if (entityId != null) { | ||
408 | + type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); | ||
409 | + } else { | ||
410 | + log.trace("[{}] entity id and type are null. Ignoring this notification", tenantId); | ||
411 | + return; | ||
412 | + } | ||
413 | + if (type == null) { | ||
414 | + log.trace("[{}] edge event type is null. Ignoring this notification [{}]", tenantId, entityId); | ||
415 | + return; | ||
416 | + } | ||
417 | + } | ||
418 | + TransportProtos.EdgeNotificationMsgProto.Builder builder = TransportProtos.EdgeNotificationMsgProto.newBuilder(); | ||
419 | + builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); | ||
420 | + builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); | ||
421 | + builder.setType(type.name()); | ||
422 | + builder.setAction(action.name()); | ||
423 | + if (entityId != null) { | ||
424 | + builder.setEntityIdMSB(entityId.getId().getMostSignificantBits()); | ||
425 | + builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits()); | ||
426 | + builder.setEntityType(entityId.getEntityType().name()); | ||
427 | + } | ||
428 | + if (edgeId != null) { | ||
429 | + builder.setEdgeIdMSB(edgeId.getId().getMostSignificantBits()); | ||
430 | + builder.setEdgeIdLSB(edgeId.getId().getLeastSignificantBits()); | ||
431 | + } | ||
432 | + if (body != null) { | ||
433 | + builder.setBody(body); | ||
434 | + } | ||
435 | + TransportProtos.EdgeNotificationMsgProto msg = builder.build(); | ||
436 | + log.trace("[{}] sending notification to edge service {}", tenantId.getId(), msg); | ||
437 | + pushMsgToCore(tenantId, entityId != null ? entityId : tenantId, TransportProtos.ToCoreMsg.newBuilder().setEdgeNotificationMsg(msg).build(), null); | ||
438 | + } | ||
439 | + | ||
372 | } | 440 | } |
@@ -26,7 +26,7 @@ import org.springframework.scheduling.annotation.Scheduled; | @@ -26,7 +26,7 @@ import org.springframework.scheduling.annotation.Scheduled; | ||
26 | import org.springframework.stereotype.Service; | 26 | import org.springframework.stereotype.Service; |
27 | import org.thingsboard.common.util.JacksonUtil; | 27 | import org.thingsboard.common.util.JacksonUtil; |
28 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 28 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
29 | -import org.thingsboard.rule.engine.api.RpcError; | 29 | +import org.thingsboard.server.common.data.rpc.RpcError; |
30 | import org.thingsboard.server.actors.ActorSystemContext; | 30 | import org.thingsboard.server.actors.ActorSystemContext; |
31 | import org.thingsboard.server.common.data.alarm.Alarm; | 31 | import org.thingsboard.server.common.data.alarm.Alarm; |
32 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -64,7 +64,7 @@ import org.thingsboard.server.service.ota.OtaPackageStateService; | @@ -64,7 +64,7 @@ import org.thingsboard.server.service.ota.OtaPackageStateService; | ||
64 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 64 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
65 | import org.thingsboard.server.service.queue.processing.AbstractConsumerService; | 65 | import org.thingsboard.server.service.queue.processing.AbstractConsumerService; |
66 | import org.thingsboard.server.service.queue.processing.IdMsgPair; | 66 | import org.thingsboard.server.service.queue.processing.IdMsgPair; |
67 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 67 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; |
68 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | 68 | import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; |
69 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 69 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
70 | import org.thingsboard.server.service.state.DeviceStateService; | 70 | import org.thingsboard.server.service.state.DeviceStateService; |
@@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
21 | import org.springframework.scheduling.annotation.Scheduled; | 21 | import org.springframework.scheduling.annotation.Scheduled; |
22 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
23 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 23 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
24 | -import org.thingsboard.rule.engine.api.RpcError; | 24 | +import org.thingsboard.server.common.data.rpc.RpcError; |
25 | import org.thingsboard.server.actors.ActorSystemContext; | 25 | import org.thingsboard.server.actors.ActorSystemContext; |
26 | import org.thingsboard.server.common.data.id.TenantId; | 26 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.common.msg.TbMsg; | 27 | import org.thingsboard.server.common.msg.TbMsg; |
@@ -55,7 +55,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr | @@ -55,7 +55,7 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStr | ||
55 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategyFactory; | 55 | import org.thingsboard.server.service.queue.processing.TbRuleEngineProcessingStrategyFactory; |
56 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; | 56 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; |
57 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory; | 57 | import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategyFactory; |
58 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | 58 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; |
59 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | 59 | import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; |
60 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; | 60 | import org.thingsboard.server.service.stats.RuleEngineStatisticsService; |
61 | 61 |
@@ -22,18 +22,19 @@ import lombok.extern.slf4j.Slf4j; | @@ -22,18 +22,19 @@ import lombok.extern.slf4j.Slf4j; | ||
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
24 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 24 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
25 | -import org.thingsboard.rule.engine.api.RpcError; | 25 | +import org.thingsboard.server.common.data.rpc.RpcError; |
26 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
27 | import org.thingsboard.server.common.data.DataConstants; | 27 | import org.thingsboard.server.common.data.DataConstants; |
28 | import org.thingsboard.server.common.data.Device; | 28 | import org.thingsboard.server.common.data.Device; |
29 | import org.thingsboard.server.common.msg.TbMsg; | 29 | import org.thingsboard.server.common.msg.TbMsg; |
30 | import org.thingsboard.server.common.msg.TbMsgDataType; | 30 | import org.thingsboard.server.common.msg.TbMsgDataType; |
31 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 31 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
32 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
32 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 33 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; |
33 | import org.thingsboard.server.dao.device.DeviceService; | 34 | import org.thingsboard.server.dao.device.DeviceService; |
34 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 35 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
35 | import org.thingsboard.server.queue.util.TbCoreComponent; | 36 | import org.thingsboard.server.queue.util.TbCoreComponent; |
36 | -import org.thingsboard.server.service.queue.TbClusterService; | 37 | +import org.thingsboard.server.cluster.TbClusterService; |
37 | import org.thingsboard.server.service.security.model.SecurityUser; | 38 | import org.thingsboard.server.service.security.model.SecurityUser; |
38 | 39 | ||
39 | import javax.annotation.PostConstruct; | 40 | import javax.annotation.PostConstruct; |
@@ -138,6 +139,12 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | @@ -138,6 +139,12 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | ||
138 | } | 139 | } |
139 | } | 140 | } |
140 | 141 | ||
142 | + @Override | ||
143 | + public void processRemoveRpc(RemoveRpcActorMsg removeRpcMsg) { | ||
144 | + log.trace("[{}][{}] Processing remove RPC [{}]", removeRpcMsg.getTenantId(), removeRpcMsg.getRequestId(), removeRpcMsg.getDeviceId()); | ||
145 | + actorContext.tellWithHighPriority(removeRpcMsg); | ||
146 | + } | ||
147 | + | ||
141 | private void sendRpcResponseToTbRuleEngine(String originServiceId, FromDeviceRpcResponse response) { | 148 | private void sendRpcResponseToTbRuleEngine(String originServiceId, FromDeviceRpcResponse response) { |
142 | if (serviceId.equals(originServiceId)) { | 149 | if (serviceId.equals(originServiceId)) { |
143 | if (tbRuleEngineRpcService.isPresent()) { | 150 | if (tbRuleEngineRpcService.isPresent()) { |
@@ -168,6 +175,8 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | @@ -168,6 +175,8 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { | ||
168 | entityNode.put("method", msg.getBody().getMethod()); | 175 | entityNode.put("method", msg.getBody().getMethod()); |
169 | entityNode.put("params", msg.getBody().getParams()); | 176 | entityNode.put("params", msg.getBody().getParams()); |
170 | 177 | ||
178 | + entityNode.put(DataConstants.ADDITIONAL_INFO, msg.getAdditionalInfo()); | ||
179 | + | ||
171 | try { | 180 | try { |
172 | TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), currentUser.getCustomerId(), metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); | 181 | TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), currentUser.getCustomerId(), metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); |
173 | clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null); | 182 | clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null); |
@@ -19,18 +19,19 @@ import lombok.extern.slf4j.Slf4j; | @@ -19,18 +19,19 @@ import lombok.extern.slf4j.Slf4j; | ||
19 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
20 | import org.springframework.stereotype.Service; | 20 | import org.springframework.stereotype.Service; |
21 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 21 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
22 | -import org.thingsboard.rule.engine.api.RpcError; | 22 | +import org.thingsboard.server.common.data.rpc.RpcError; |
23 | import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest; | 23 | import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest; |
24 | import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcResponse; | 24 | import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcResponse; |
25 | import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; | 25 | import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; |
26 | import org.thingsboard.server.common.msg.queue.ServiceType; | 26 | import org.thingsboard.server.common.msg.queue.ServiceType; |
27 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 27 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
28 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
28 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 29 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; |
29 | import org.thingsboard.server.gen.transport.TransportProtos; | 30 | import org.thingsboard.server.gen.transport.TransportProtos; |
30 | import org.thingsboard.server.queue.discovery.PartitionService; | 31 | import org.thingsboard.server.queue.discovery.PartitionService; |
31 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 32 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
32 | import org.thingsboard.server.queue.util.TbRuleEngineComponent; | 33 | import org.thingsboard.server.queue.util.TbRuleEngineComponent; |
33 | -import org.thingsboard.server.service.queue.TbClusterService; | 34 | +import org.thingsboard.server.cluster.TbClusterService; |
34 | 35 | ||
35 | import javax.annotation.PostConstruct; | 36 | import javax.annotation.PostConstruct; |
36 | import javax.annotation.PreDestroy; | 37 | import javax.annotation.PreDestroy; |
@@ -100,7 +101,7 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi | @@ -100,7 +101,7 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi | ||
100 | @Override | 101 | @Override |
101 | public void sendRpcRequestToDevice(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) { | 102 | public void sendRpcRequestToDevice(RuleEngineDeviceRpcRequest src, Consumer<RuleEngineDeviceRpcResponse> consumer) { |
102 | ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), src.getTenantId(), src.getDeviceId(), | 103 | ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), src.getTenantId(), src.getDeviceId(), |
103 | - src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()), src.isPersisted()); | 104 | + src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()), src.isPersisted(), src.getAdditionalInfo()); |
104 | forwardRpcRequestToDeviceActor(request, response -> { | 105 | forwardRpcRequestToDeviceActor(request, response -> { |
105 | if (src.isRestApiCall()) { | 106 | if (src.isRestApiCall()) { |
106 | sendRpcResponseToTbCore(src.getOriginServiceId(), response); | 107 | sendRpcResponseToTbCore(src.getOriginServiceId(), response); |
@@ -18,10 +18,11 @@ package org.thingsboard.server.service.rpc; | @@ -18,10 +18,11 @@ package org.thingsboard.server.service.rpc; | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | import lombok.RequiredArgsConstructor; | 19 | import lombok.RequiredArgsConstructor; |
20 | import lombok.ToString; | 20 | import lombok.ToString; |
21 | -import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | 21 | +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; |
22 | import org.thingsboard.server.common.data.id.DeviceId; | 22 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.msg.MsgType; | 24 | import org.thingsboard.server.common.msg.MsgType; |
25 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
25 | 26 | ||
26 | @ToString | 27 | @ToString |
27 | @RequiredArgsConstructor | 28 | @RequiredArgsConstructor |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.rpc; | ||
17 | + | ||
18 | +import lombok.Getter; | ||
19 | +import lombok.RequiredArgsConstructor; | ||
20 | +import lombok.ToString; | ||
21 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
22 | +import org.thingsboard.server.common.data.id.TenantId; | ||
23 | +import org.thingsboard.server.common.msg.MsgType; | ||
24 | +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; | ||
25 | + | ||
26 | +import java.util.UUID; | ||
27 | + | ||
28 | +@ToString | ||
29 | +@RequiredArgsConstructor | ||
30 | +public class RemoveRpcActorMsg implements ToDeviceActorNotificationMsg { | ||
31 | + | ||
32 | + @Getter | ||
33 | + private final TenantId tenantId; | ||
34 | + @Getter | ||
35 | + private final DeviceId deviceId; | ||
36 | + | ||
37 | + @Getter | ||
38 | + private final UUID requestId; | ||
39 | + | ||
40 | + @Override | ||
41 | + public MsgType getMsgType() { | ||
42 | + return MsgType.REMOVE_RPC_TO_DEVICE_ACTOR_MSG; | ||
43 | + } | ||
44 | +} |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.rpc; | 16 | package org.thingsboard.server.service.rpc; |
17 | 17 | ||
18 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
18 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; | 19 | import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; |
19 | import org.thingsboard.server.service.security.model.SecurityUser; | 20 | import org.thingsboard.server.service.security.model.SecurityUser; |
20 | 21 | ||
@@ -55,4 +56,6 @@ public interface TbCoreDeviceRpcService { | @@ -55,4 +56,6 @@ public interface TbCoreDeviceRpcService { | ||
55 | */ | 56 | */ |
56 | void processRpcResponseFromDeviceActor(FromDeviceRpcResponse response); | 57 | void processRpcResponseFromDeviceActor(FromDeviceRpcResponse response); |
57 | 58 | ||
59 | + void processRemoveRpc(RemoveRpcActorMsg removeRpcMsg); | ||
60 | + | ||
58 | } | 61 | } |
@@ -31,7 +31,7 @@ import org.thingsboard.server.common.msg.TbMsg; | @@ -31,7 +31,7 @@ import org.thingsboard.server.common.msg.TbMsg; | ||
31 | import org.thingsboard.server.common.msg.TbMsgMetaData; | 31 | import org.thingsboard.server.common.msg.TbMsgMetaData; |
32 | import org.thingsboard.server.dao.rpc.RpcService; | 32 | import org.thingsboard.server.dao.rpc.RpcService; |
33 | import org.thingsboard.server.queue.util.TbCoreComponent; | 33 | import org.thingsboard.server.queue.util.TbCoreComponent; |
34 | -import org.thingsboard.server.service.queue.TbClusterService; | 34 | +import org.thingsboard.server.cluster.TbClusterService; |
35 | 35 | ||
36 | @TbCoreComponent | 36 | @TbCoreComponent |
37 | @Service | 37 | @Service |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.service.rpc; | 16 | package org.thingsboard.server.service.rpc; |
17 | 17 | ||
18 | import org.thingsboard.rule.engine.api.RuleEngineRpcService; | 18 | import org.thingsboard.rule.engine.api.RuleEngineRpcService; |
19 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * Created by ashvayka on 16.04.18. | 22 | * Created by ashvayka on 16.04.18. |
@@ -18,7 +18,7 @@ package org.thingsboard.server.service.rpc; | @@ -18,7 +18,7 @@ package org.thingsboard.server.service.rpc; | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | import lombok.RequiredArgsConstructor; | 19 | import lombok.RequiredArgsConstructor; |
20 | import lombok.ToString; | 20 | import lombok.ToString; |
21 | -import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | 21 | +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; |
22 | import org.thingsboard.server.common.data.id.DeviceId; | 22 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.msg.MsgType; | 24 | import org.thingsboard.server.common.msg.MsgType; |
@@ -47,7 +47,7 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache; | @@ -47,7 +47,7 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache; | ||
47 | import org.thingsboard.server.dao.tenant.TenantService; | 47 | import org.thingsboard.server.dao.tenant.TenantService; |
48 | import org.thingsboard.server.dao.user.UserService; | 48 | import org.thingsboard.server.dao.user.UserService; |
49 | import org.thingsboard.server.service.install.InstallScripts; | 49 | import org.thingsboard.server.service.install.InstallScripts; |
50 | -import org.thingsboard.server.service.queue.TbClusterService; | 50 | +import org.thingsboard.server.cluster.TbClusterService; |
51 | import org.thingsboard.server.service.security.model.SecurityUser; | 51 | import org.thingsboard.server.service.security.model.SecurityUser; |
52 | import org.thingsboard.server.service.security.model.UserPrincipal; | 52 | import org.thingsboard.server.service.security.model.UserPrincipal; |
53 | 53 | ||
@@ -180,7 +180,7 @@ public abstract class AbstractOAuth2ClientMapper { | @@ -180,7 +180,7 @@ public abstract class AbstractOAuth2ClientMapper { | ||
180 | installScripts.createDefaultEdgeRuleChains(tenant.getId()); | 180 | installScripts.createDefaultEdgeRuleChains(tenant.getId()); |
181 | tenantProfileCache.evict(tenant.getId()); | 181 | tenantProfileCache.evict(tenant.getId()); |
182 | tbClusterService.onTenantChange(tenant, null); | 182 | tbClusterService.onTenantChange(tenant, null); |
183 | - tbClusterService.onEntityStateChange(tenant.getId(), tenant.getId(), | 183 | + tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), |
184 | ComponentLifecycleEvent.CREATED); | 184 | ComponentLifecycleEvent.CREATED); |
185 | } else { | 185 | } else { |
186 | tenant = tenants.get(0); | 186 | tenant = tenants.get(0); |
@@ -17,6 +17,7 @@ package org.thingsboard.server.service.security.auth.oauth2; | @@ -17,6 +17,7 @@ package org.thingsboard.server.service.security.auth.oauth2; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.core.JsonProcessingException; | 18 | import com.fasterxml.jackson.core.JsonProcessingException; |
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | ||
20 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
21 | import org.springframework.boot.web.client.RestTemplateBuilder; | 22 | import org.springframework.boot.web.client.RestTemplateBuilder; |
22 | import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; | 23 | import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; |
@@ -29,6 +30,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | @@ -29,6 +30,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2Registration; | ||
29 | import org.thingsboard.server.dao.oauth2.OAuth2User; | 30 | import org.thingsboard.server.dao.oauth2.OAuth2User; |
30 | import org.thingsboard.server.service.security.model.SecurityUser; | 31 | import org.thingsboard.server.service.security.model.SecurityUser; |
31 | 32 | ||
33 | +import javax.annotation.PostConstruct; | ||
32 | import javax.servlet.http.HttpServletRequest; | 34 | import javax.servlet.http.HttpServletRequest; |
33 | 35 | ||
34 | @Service(value = "customOAuth2ClientMapper") | 36 | @Service(value = "customOAuth2ClientMapper") |
@@ -40,6 +42,15 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme | @@ -40,6 +42,15 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme | ||
40 | 42 | ||
41 | private RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); | 43 | private RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); |
42 | 44 | ||
45 | + @PostConstruct | ||
46 | + public void init() { | ||
47 | + // Register time module to parse Instant objects. | ||
48 | + // com.fasterxml.jackson.databind.exc.InvalidDefinitionException: | ||
49 | + // Java 8 date/time type `java.time.Instant` not supported by default: | ||
50 | + // add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling | ||
51 | + json.registerModule(new JavaTimeModule()); | ||
52 | + } | ||
53 | + | ||
43 | @Override | 54 | @Override |
44 | public SecurityUser getOrCreateUserByClientPrincipal(HttpServletRequest request, OAuth2AuthenticationToken token, String providerAccessToken, OAuth2Registration registration) { | 55 | public SecurityUser getOrCreateUserByClientPrincipal(HttpServletRequest request, OAuth2AuthenticationToken token, String providerAccessToken, OAuth2Registration registration) { |
45 | OAuth2MapperConfig config = registration.getMapperConfig(); | 56 | OAuth2MapperConfig config = registration.getMapperConfig(); |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.security.auth.oauth2; | 16 | package org.thingsboard.server.service.security.auth.oauth2; |
17 | 17 | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
18 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
19 | import org.springframework.security.core.Authentication; | 20 | import org.springframework.security.core.Authentication; |
20 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; | 21 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; |
@@ -42,6 +43,7 @@ import java.net.URLEncoder; | @@ -42,6 +43,7 @@ import java.net.URLEncoder; | ||
42 | import java.nio.charset.StandardCharsets; | 43 | import java.nio.charset.StandardCharsets; |
43 | import java.util.UUID; | 44 | import java.util.UUID; |
44 | 45 | ||
46 | +@Slf4j | ||
45 | @Component(value = "oauth2AuthenticationSuccessHandler") | 47 | @Component(value = "oauth2AuthenticationSuccessHandler") |
46 | public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { | 48 | public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { |
47 | 49 | ||
@@ -99,6 +101,8 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS | @@ -99,6 +101,8 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS | ||
99 | clearAuthenticationAttributes(request, response); | 101 | clearAuthenticationAttributes(request, response); |
100 | getRedirectStrategy().sendRedirect(request, response, baseUrl + "/?accessToken=" + accessToken.getToken() + "&refreshToken=" + refreshToken.getToken()); | 102 | getRedirectStrategy().sendRedirect(request, response, baseUrl + "/?accessToken=" + accessToken.getToken() + "&refreshToken=" + refreshToken.getToken()); |
101 | } catch (Exception e) { | 103 | } catch (Exception e) { |
104 | + log.debug("Error occurred during processing authentication success result. " + | ||
105 | + "request [{}], response [{}], authentication [{}]", request, response, authentication, e); | ||
102 | clearAuthenticationAttributes(request, response); | 106 | clearAuthenticationAttributes(request, response); |
103 | String errorPrefix; | 107 | String errorPrefix; |
104 | if (!StringUtils.isEmpty(callbackUrlScheme)) { | 108 | if (!StringUtils.isEmpty(callbackUrlScheme)) { |
@@ -22,7 +22,6 @@ import com.google.common.util.concurrent.Futures; | @@ -22,7 +22,6 @@ import com.google.common.util.concurrent.Futures; | ||
22 | import com.google.common.util.concurrent.ListenableFuture; | 22 | import com.google.common.util.concurrent.ListenableFuture; |
23 | import com.google.common.util.concurrent.ListeningScheduledExecutorService; | 23 | import com.google.common.util.concurrent.ListeningScheduledExecutorService; |
24 | import com.google.common.util.concurrent.MoreExecutors; | 24 | import com.google.common.util.concurrent.MoreExecutors; |
25 | -import com.google.common.util.concurrent.SettableFuture; | ||
26 | import lombok.Getter; | 25 | import lombok.Getter; |
27 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
28 | import org.springframework.beans.factory.annotation.Autowired; | 27 | import org.springframework.beans.factory.annotation.Autowired; |
@@ -59,7 +58,7 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | @@ -59,7 +58,7 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | ||
59 | import org.thingsboard.server.queue.discovery.PartitionService; | 58 | import org.thingsboard.server.queue.discovery.PartitionService; |
60 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 59 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
61 | import org.thingsboard.server.queue.util.TbCoreComponent; | 60 | import org.thingsboard.server.queue.util.TbCoreComponent; |
62 | -import org.thingsboard.server.service.queue.TbClusterService; | 61 | +import org.thingsboard.server.cluster.TbClusterService; |
63 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; | 62 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
64 | 63 | ||
65 | import javax.annotation.Nonnull; | 64 | import javax.annotation.Nonnull; |
@@ -71,7 +70,6 @@ import java.util.Arrays; | @@ -71,7 +70,6 @@ import java.util.Arrays; | ||
71 | import java.util.Collections; | 70 | import java.util.Collections; |
72 | import java.util.HashSet; | 71 | import java.util.HashSet; |
73 | import java.util.List; | 72 | import java.util.List; |
74 | -import java.util.Optional; | ||
75 | import java.util.Queue; | 73 | import java.util.Queue; |
76 | import java.util.Random; | 74 | import java.util.Random; |
77 | import java.util.Set; | 75 | import java.util.Set; |
@@ -137,7 +135,6 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -137,7 +135,6 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
137 | private ExecutorService deviceStateExecutor; | 135 | private ExecutorService deviceStateExecutor; |
138 | private final ConcurrentMap<TopicPartitionInfo, Set<DeviceId>> partitionedDevices = new ConcurrentHashMap<>(); | 136 | private final ConcurrentMap<TopicPartitionInfo, Set<DeviceId>> partitionedDevices = new ConcurrentHashMap<>(); |
139 | final ConcurrentMap<DeviceId, DeviceStateData> deviceStates = new ConcurrentHashMap<>(); | 137 | final ConcurrentMap<DeviceId, DeviceStateData> deviceStates = new ConcurrentHashMap<>(); |
140 | - private final ConcurrentMap<DeviceId, Long> deviceLastSavedActivity = new ConcurrentHashMap<>(); | ||
141 | 138 | ||
142 | final Queue<Set<TopicPartitionInfo>> subscribeQueue = new ConcurrentLinkedQueue<>(); | 139 | final Queue<Set<TopicPartitionInfo>> subscribeQueue = new ConcurrentLinkedQueue<>(); |
143 | 140 | ||
@@ -177,22 +174,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -177,22 +174,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
177 | } | 174 | } |
178 | 175 | ||
179 | @Override | 176 | @Override |
180 | - public void onDeviceAdded(Device device) { | ||
181 | - sendDeviceEvent(device.getTenantId(), device.getId(), true, false, false); | ||
182 | - } | ||
183 | - | ||
184 | - @Override | ||
185 | - public void onDeviceUpdated(Device device) { | ||
186 | - sendDeviceEvent(device.getTenantId(), device.getId(), false, true, false); | ||
187 | - } | ||
188 | - | ||
189 | - @Override | ||
190 | - public void onDeviceDeleted(Device device) { | ||
191 | - sendDeviceEvent(device.getTenantId(), device.getId(), false, false, true); | ||
192 | - } | ||
193 | - | ||
194 | - @Override | ||
195 | - public void onDeviceConnect(DeviceId deviceId) { | 177 | + public void onDeviceConnect(TenantId tenantId, DeviceId deviceId) { |
196 | log.trace("on Device Connect [{}]", deviceId.getId()); | 178 | log.trace("on Device Connect [{}]", deviceId.getId()); |
197 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); | 179 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); |
198 | long ts = System.currentTimeMillis(); | 180 | long ts = System.currentTimeMillis(); |
@@ -200,23 +182,23 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -200,23 +182,23 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
200 | save(deviceId, LAST_CONNECT_TIME, ts); | 182 | save(deviceId, LAST_CONNECT_TIME, ts); |
201 | pushRuleEngineMessage(stateData, CONNECT_EVENT); | 183 | pushRuleEngineMessage(stateData, CONNECT_EVENT); |
202 | checkAndUpdateState(deviceId, stateData); | 184 | checkAndUpdateState(deviceId, stateData); |
185 | + cleanDeviceStateIfBelongsExternalPartition(tenantId, deviceId); | ||
203 | } | 186 | } |
204 | 187 | ||
205 | @Override | 188 | @Override |
206 | - public void onDeviceActivity(DeviceId deviceId, long lastReportedActivity) { | 189 | + public void onDeviceActivity(TenantId tenantId, DeviceId deviceId, long lastReportedActivity) { |
207 | log.trace("on Device Activity [{}], lastReportedActivity [{}]", deviceId.getId(), lastReportedActivity); | 190 | log.trace("on Device Activity [{}], lastReportedActivity [{}]", deviceId.getId(), lastReportedActivity); |
208 | - long lastSavedActivity = deviceLastSavedActivity.getOrDefault(deviceId, 0L); | ||
209 | - if (lastReportedActivity > 0 && lastReportedActivity > lastSavedActivity) { | ||
210 | - final DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); | 191 | + final DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); |
192 | + if (lastReportedActivity > 0 && lastReportedActivity > stateData.getState().getLastActivityTime()) { | ||
211 | updateActivityState(deviceId, stateData, lastReportedActivity); | 193 | updateActivityState(deviceId, stateData, lastReportedActivity); |
212 | } | 194 | } |
195 | + cleanDeviceStateIfBelongsExternalPartition(tenantId, deviceId); | ||
213 | } | 196 | } |
214 | 197 | ||
215 | void updateActivityState(DeviceId deviceId, DeviceStateData stateData, long lastReportedActivity) { | 198 | void updateActivityState(DeviceId deviceId, DeviceStateData stateData, long lastReportedActivity) { |
216 | log.trace("updateActivityState - fetched state {} for device {}, lastReportedActivity {}", stateData, deviceId, lastReportedActivity); | 199 | log.trace("updateActivityState - fetched state {} for device {}, lastReportedActivity {}", stateData, deviceId, lastReportedActivity); |
217 | if (stateData != null) { | 200 | if (stateData != null) { |
218 | save(deviceId, LAST_ACTIVITY_TIME, lastReportedActivity); | 201 | save(deviceId, LAST_ACTIVITY_TIME, lastReportedActivity); |
219 | - deviceLastSavedActivity.put(deviceId, lastReportedActivity); | ||
220 | DeviceState state = stateData.getState(); | 202 | DeviceState state = stateData.getState(); |
221 | state.setLastActivityTime(lastReportedActivity); | 203 | state.setLastActivityTime(lastReportedActivity); |
222 | if (!state.isActive()) { | 204 | if (!state.isActive()) { |
@@ -225,21 +207,23 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -225,21 +207,23 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
225 | pushRuleEngineMessage(stateData, ACTIVITY_EVENT); | 207 | pushRuleEngineMessage(stateData, ACTIVITY_EVENT); |
226 | } | 208 | } |
227 | } else { | 209 | } else { |
228 | - log.warn("updateActivityState - fetched state IN NULL for device {}, lastReportedActivity {}", deviceId, lastReportedActivity); | 210 | + log.debug("updateActivityState - fetched state IN NULL for device {}, lastReportedActivity {}", deviceId, lastReportedActivity); |
211 | + cleanUpDeviceStateMap(deviceId); | ||
229 | } | 212 | } |
230 | } | 213 | } |
231 | 214 | ||
232 | @Override | 215 | @Override |
233 | - public void onDeviceDisconnect(DeviceId deviceId) { | 216 | + public void onDeviceDisconnect(TenantId tenantId, DeviceId deviceId) { |
234 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); | 217 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); |
235 | long ts = System.currentTimeMillis(); | 218 | long ts = System.currentTimeMillis(); |
236 | stateData.getState().setLastDisconnectTime(ts); | 219 | stateData.getState().setLastDisconnectTime(ts); |
237 | save(deviceId, LAST_DISCONNECT_TIME, ts); | 220 | save(deviceId, LAST_DISCONNECT_TIME, ts); |
238 | pushRuleEngineMessage(stateData, DISCONNECT_EVENT); | 221 | pushRuleEngineMessage(stateData, DISCONNECT_EVENT); |
222 | + cleanDeviceStateIfBelongsExternalPartition(tenantId, deviceId); | ||
239 | } | 223 | } |
240 | 224 | ||
241 | @Override | 225 | @Override |
242 | - public void onDeviceInactivityTimeoutUpdate(DeviceId deviceId, long inactivityTimeout) { | 226 | + public void onDeviceInactivityTimeoutUpdate(TenantId tenantId, DeviceId deviceId, long inactivityTimeout) { |
243 | if (inactivityTimeout <= 0L) { | 227 | if (inactivityTimeout <= 0L) { |
244 | return; | 228 | return; |
245 | } | 229 | } |
@@ -247,6 +231,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -247,6 +231,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
247 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); | 231 | DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); |
248 | stateData.getState().setInactivityTimeout(inactivityTimeout); | 232 | stateData.getState().setInactivityTimeout(inactivityTimeout); |
249 | checkAndUpdateState(deviceId, stateData); | 233 | checkAndUpdateState(deviceId, stateData); |
234 | + cleanDeviceStateIfBelongsExternalPartition(tenantId, deviceId); | ||
250 | } | 235 | } |
251 | 236 | ||
252 | @Override | 237 | @Override |
@@ -267,6 +252,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -267,6 +252,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
267 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, device.getId()); | 252 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, device.getId()); |
268 | if (partitionedDevices.containsKey(tpi)) { | 253 | if (partitionedDevices.containsKey(tpi)) { |
269 | addDeviceUsingState(tpi, state); | 254 | addDeviceUsingState(tpi, state); |
255 | + save(deviceId, ACTIVITY_STATE, false); | ||
270 | callback.onSuccess(); | 256 | callback.onSuccess(); |
271 | } else { | 257 | } else { |
272 | log.warn("[{}][{}] Device belongs to external partition. Probably rebalancing is in progress. Topic: {}" | 258 | log.warn("[{}][{}] Device belongs to external partition. Probably rebalancing is in progress. Topic: {}" |
@@ -283,12 +269,11 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -283,12 +269,11 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
283 | }, deviceStateExecutor); | 269 | }, deviceStateExecutor); |
284 | } else if (proto.getUpdated()) { | 270 | } else if (proto.getUpdated()) { |
285 | DeviceStateData stateData = getOrFetchDeviceStateData(device.getId()); | 271 | DeviceStateData stateData = getOrFetchDeviceStateData(device.getId()); |
286 | - if (stateData != null) { | ||
287 | - TbMsgMetaData md = new TbMsgMetaData(); | ||
288 | - md.putValue("deviceName", device.getName()); | ||
289 | - md.putValue("deviceType", device.getType()); | ||
290 | - stateData.setMetaData(md); | ||
291 | - } | 272 | + TbMsgMetaData md = new TbMsgMetaData(); |
273 | + md.putValue("deviceName", device.getName()); | ||
274 | + md.putValue("deviceType", device.getType()); | ||
275 | + stateData.setMetaData(md); | ||
276 | + callback.onSuccess(); | ||
292 | } | 277 | } |
293 | } else { | 278 | } else { |
294 | //Device was probably deleted while message was in queue; | 279 | //Device was probably deleted while message was in queue; |
@@ -356,10 +341,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -356,10 +341,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
356 | // We no longer manage current partition of devices; | 341 | // We no longer manage current partition of devices; |
357 | removedPartitions.forEach(partition -> { | 342 | removedPartitions.forEach(partition -> { |
358 | Set<DeviceId> devices = partitionedDevices.remove(partition); | 343 | Set<DeviceId> devices = partitionedDevices.remove(partition); |
359 | - devices.forEach(deviceId -> { | ||
360 | - deviceStates.remove(deviceId); | ||
361 | - deviceLastSavedActivity.remove(deviceId); | ||
362 | - }); | 344 | + devices.forEach(this::cleanUpDeviceStateMap); |
363 | }); | 345 | }); |
364 | 346 | ||
365 | addedPartitions.forEach(tpi -> partitionedDevices.computeIfAbsent(tpi, key -> ConcurrentHashMap.newKeySet())); | 347 | addedPartitions.forEach(tpi -> partitionedDevices.computeIfAbsent(tpi, key -> ConcurrentHashMap.newKeySet())); |
@@ -457,17 +439,18 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -457,17 +439,18 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
457 | deviceStates.put(state.getDeviceId(), state); | 439 | deviceStates.put(state.getDeviceId(), state); |
458 | } else { | 440 | } else { |
459 | log.warn("Device belongs to external partition {}" + tpi.getFullTopicName()); | 441 | log.warn("Device belongs to external partition {}" + tpi.getFullTopicName()); |
460 | - new RuntimeException("Device belongs to external partition " + tpi.getFullTopicName() + "!"); | 442 | + throw new RuntimeException("Device belongs to external partition " + tpi.getFullTopicName() + "!"); |
461 | } | 443 | } |
462 | } | 444 | } |
463 | 445 | ||
464 | void updateInactivityStateIfExpired() { | 446 | void updateInactivityStateIfExpired() { |
465 | final long ts = System.currentTimeMillis(); | 447 | final long ts = System.currentTimeMillis(); |
466 | - log.debug("Calculating state updates for {} devices", deviceStates.size()); | ||
467 | - Set<DeviceId> deviceIds = new HashSet<>(deviceStates.keySet()); | ||
468 | - for (DeviceId deviceId : deviceIds) { | ||
469 | - updateInactivityStateIfExpired(ts, deviceId); | ||
470 | - } | 448 | + partitionedDevices.forEach((tpi, deviceIds) -> { |
449 | + log.debug("Calculating state updates. tpi {} for {} devices", tpi.getFullTopicName(), deviceIds.size()); | ||
450 | + for (DeviceId deviceId : deviceIds) { | ||
451 | + updateInactivityStateIfExpired(ts, deviceId); | ||
452 | + } | ||
453 | + }); | ||
471 | } | 454 | } |
472 | 455 | ||
473 | void updateInactivityStateIfExpired(long ts, DeviceId deviceId) { | 456 | void updateInactivityStateIfExpired(long ts, DeviceId deviceId) { |
@@ -488,8 +471,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -488,8 +471,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
488 | } | 471 | } |
489 | } else { | 472 | } else { |
490 | log.debug("[{}] Device that belongs to other server is detected and removed.", deviceId); | 473 | log.debug("[{}] Device that belongs to other server is detected and removed.", deviceId); |
491 | - deviceStates.remove(deviceId); | ||
492 | - deviceLastSavedActivity.remove(deviceId); | 474 | + cleanUpDeviceStateMap(deviceId); |
493 | } | 475 | } |
494 | } | 476 | } |
495 | 477 | ||
@@ -522,27 +504,26 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -522,27 +504,26 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
522 | } | 504 | } |
523 | } | 505 | } |
524 | 506 | ||
525 | - private void sendDeviceEvent(TenantId tenantId, DeviceId deviceId, boolean added, boolean updated, boolean deleted) { | ||
526 | - TransportProtos.DeviceStateServiceMsgProto.Builder builder = TransportProtos.DeviceStateServiceMsgProto.newBuilder(); | ||
527 | - builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); | ||
528 | - builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); | ||
529 | - builder.setDeviceIdMSB(deviceId.getId().getMostSignificantBits()); | ||
530 | - builder.setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()); | ||
531 | - builder.setAdded(added); | ||
532 | - builder.setUpdated(updated); | ||
533 | - builder.setDeleted(deleted); | ||
534 | - TransportProtos.DeviceStateServiceMsgProto msg = builder.build(); | ||
535 | - clusterService.pushMsgToCore(tenantId, deviceId, TransportProtos.ToCoreMsg.newBuilder().setDeviceStateServiceMsg(msg).build(), null); | 507 | + private void cleanDeviceStateIfBelongsExternalPartition(TenantId tenantId, final DeviceId deviceId) { |
508 | + TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, deviceId); | ||
509 | + if (!partitionedDevices.containsKey(tpi)) { | ||
510 | + cleanUpDeviceStateMap(deviceId); | ||
511 | + log.debug("[{}][{}] device belongs to external partition. Probably rebalancing is in progress. Topic: {}" | ||
512 | + , tenantId, deviceId, tpi.getFullTopicName()); | ||
513 | + } | ||
536 | } | 514 | } |
537 | 515 | ||
538 | private void onDeviceDeleted(TenantId tenantId, DeviceId deviceId) { | 516 | private void onDeviceDeleted(TenantId tenantId, DeviceId deviceId) { |
539 | - deviceStates.remove(deviceId); | ||
540 | - deviceLastSavedActivity.remove(deviceId); | 517 | + cleanUpDeviceStateMap(deviceId); |
541 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, deviceId); | 518 | TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, deviceId); |
542 | Set<DeviceId> deviceIdSet = partitionedDevices.get(tpi); | 519 | Set<DeviceId> deviceIdSet = partitionedDevices.get(tpi); |
543 | deviceIdSet.remove(deviceId); | 520 | deviceIdSet.remove(deviceId); |
544 | } | 521 | } |
545 | 522 | ||
523 | + private void cleanUpDeviceStateMap(DeviceId deviceId) { | ||
524 | + deviceStates.remove(deviceId); | ||
525 | + } | ||
526 | + | ||
546 | private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) { | 527 | private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) { |
547 | ListenableFuture<DeviceStateData> future; | 528 | ListenableFuture<DeviceStateData> future; |
548 | if (persistToTelemetry) { | 529 | if (persistToTelemetry) { |
@@ -573,7 +554,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -573,7 +554,7 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
573 | } | 554 | } |
574 | 555 | ||
575 | private <T extends KvEntry> Function<List<T>, DeviceStateData> extractDeviceStateData(Device device) { | 556 | private <T extends KvEntry> Function<List<T>, DeviceStateData> extractDeviceStateData(Device device) { |
576 | - return new Function<List<T>, DeviceStateData>() { | 557 | + return new Function<>() { |
577 | @Nonnull | 558 | @Nonnull |
578 | @Override | 559 | @Override |
579 | public DeviceStateData apply(@Nullable List<T> data) { | 560 | public DeviceStateData apply(@Nullable List<T> data) { |
@@ -660,9 +641,9 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -660,9 +641,9 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
660 | tsSubService.saveAndNotifyInternal( | 641 | tsSubService.saveAndNotifyInternal( |
661 | TenantId.SYS_TENANT_ID, deviceId, | 642 | TenantId.SYS_TENANT_ID, deviceId, |
662 | Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))), | 643 | Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))), |
663 | - new AttributeSaveCallback<>(deviceId, key, value)); | 644 | + new TelemetrySaveCallback<>(deviceId, key, value)); |
664 | } else { | 645 | } else { |
665 | - tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback<>(deviceId, key, value)); | 646 | + tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); |
666 | } | 647 | } |
667 | } | 648 | } |
668 | 649 | ||
@@ -671,18 +652,18 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | @@ -671,18 +652,18 @@ public class DefaultDeviceStateService extends TbApplicationEventListener<Partit | ||
671 | tsSubService.saveAndNotifyInternal( | 652 | tsSubService.saveAndNotifyInternal( |
672 | TenantId.SYS_TENANT_ID, deviceId, | 653 | TenantId.SYS_TENANT_ID, deviceId, |
673 | Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))), | 654 | Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))), |
674 | - new AttributeSaveCallback<>(deviceId, key, value)); | 655 | + new TelemetrySaveCallback<>(deviceId, key, value)); |
675 | } else { | 656 | } else { |
676 | - tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback<>(deviceId, key, value)); | 657 | + tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); |
677 | } | 658 | } |
678 | } | 659 | } |
679 | 660 | ||
680 | - private static class AttributeSaveCallback<T> implements FutureCallback<T> { | 661 | + private static class TelemetrySaveCallback<T> implements FutureCallback<T> { |
681 | private final DeviceId deviceId; | 662 | private final DeviceId deviceId; |
682 | private final String key; | 663 | private final String key; |
683 | private final Object value; | 664 | private final Object value; |
684 | 665 | ||
685 | - AttributeSaveCallback(DeviceId deviceId, String key, Object value) { | 666 | + TelemetrySaveCallback(DeviceId deviceId, String key, Object value) { |
686 | this.deviceId = deviceId; | 667 | this.deviceId = deviceId; |
687 | this.key = key; | 668 | this.key = key; |
688 | this.value = value; | 669 | this.value = value; |
@@ -18,6 +18,7 @@ package org.thingsboard.server.service.state; | @@ -18,6 +18,7 @@ package org.thingsboard.server.service.state; | ||
18 | import org.springframework.context.ApplicationListener; | 18 | import org.springframework.context.ApplicationListener; |
19 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
20 | import org.thingsboard.server.common.data.id.DeviceId; | 20 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | +import org.thingsboard.server.common.data.id.TenantId; | ||
21 | import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | 22 | import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
22 | import org.thingsboard.server.gen.transport.TransportProtos; | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
23 | import org.thingsboard.server.common.msg.queue.TbCallback; | 24 | import org.thingsboard.server.common.msg.queue.TbCallback; |
@@ -27,19 +28,13 @@ import org.thingsboard.server.common.msg.queue.TbCallback; | @@ -27,19 +28,13 @@ import org.thingsboard.server.common.msg.queue.TbCallback; | ||
27 | */ | 28 | */ |
28 | public interface DeviceStateService extends ApplicationListener<PartitionChangeEvent> { | 29 | public interface DeviceStateService extends ApplicationListener<PartitionChangeEvent> { |
29 | 30 | ||
30 | - void onDeviceAdded(Device device); | 31 | + void onDeviceConnect(TenantId tenantId, DeviceId deviceId); |
31 | 32 | ||
32 | - void onDeviceUpdated(Device device); | 33 | + void onDeviceActivity(TenantId tenantId, DeviceId deviceId, long lastReportedActivityTime); |
33 | 34 | ||
34 | - void onDeviceDeleted(Device device); | 35 | + void onDeviceDisconnect(TenantId tenantId, DeviceId deviceId); |
35 | 36 | ||
36 | - void onDeviceConnect(DeviceId deviceId); | ||
37 | - | ||
38 | - void onDeviceActivity(DeviceId deviceId, long lastReportedActivityTime); | ||
39 | - | ||
40 | - void onDeviceDisconnect(DeviceId deviceId); | ||
41 | - | ||
42 | - void onDeviceInactivityTimeoutUpdate(DeviceId deviceId, long inactivityTimeout); | 37 | + void onDeviceInactivityTimeoutUpdate(TenantId tenantId, DeviceId deviceId, long inactivityTimeout); |
43 | 38 | ||
44 | void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto proto, TbCallback bytes); | 39 | void onQueueMsg(TransportProtos.DeviceStateServiceMsgProto proto, TbCallback bytes); |
45 | 40 |
@@ -53,7 +53,7 @@ import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | @@ -53,7 +53,7 @@ import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | ||
53 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | 53 | import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; |
54 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; | 54 | import org.thingsboard.server.queue.provider.TbQueueProducerProvider; |
55 | import org.thingsboard.server.queue.util.TbCoreComponent; | 55 | import org.thingsboard.server.queue.util.TbCoreComponent; |
56 | -import org.thingsboard.server.service.queue.TbClusterService; | 56 | +import org.thingsboard.server.cluster.TbClusterService; |
57 | import org.thingsboard.server.service.state.DefaultDeviceStateService; | 57 | import org.thingsboard.server.service.state.DefaultDeviceStateService; |
58 | import org.thingsboard.server.service.state.DeviceStateService; | 58 | import org.thingsboard.server.service.state.DeviceStateService; |
59 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | 59 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
@@ -224,7 +224,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | @@ -224,7 +224,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | ||
224 | return subscriptionUpdate; | 224 | return subscriptionUpdate; |
225 | }); | 225 | }); |
226 | if (entityId.getEntityType() == EntityType.DEVICE) { | 226 | if (entityId.getEntityType() == EntityType.DEVICE) { |
227 | - updateDeviceInactivityTimeout(entityId, ts); | 227 | + updateDeviceInactivityTimeout(tenantId, entityId, ts); |
228 | } | 228 | } |
229 | callback.onSuccess(); | 229 | callback.onSuccess(); |
230 | } | 230 | } |
@@ -259,7 +259,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | @@ -259,7 +259,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | ||
259 | }); | 259 | }); |
260 | if (entityId.getEntityType() == EntityType.DEVICE) { | 260 | if (entityId.getEntityType() == EntityType.DEVICE) { |
261 | if (TbAttributeSubscriptionScope.SERVER_SCOPE.name().equalsIgnoreCase(scope)) { | 261 | if (TbAttributeSubscriptionScope.SERVER_SCOPE.name().equalsIgnoreCase(scope)) { |
262 | - updateDeviceInactivityTimeout(entityId, attributes); | 262 | + updateDeviceInactivityTimeout(tenantId, entityId, attributes); |
263 | } else if (TbAttributeSubscriptionScope.SHARED_SCOPE.name().equalsIgnoreCase(scope) && notifyDevice) { | 263 | } else if (TbAttributeSubscriptionScope.SHARED_SCOPE.name().equalsIgnoreCase(scope) && notifyDevice) { |
264 | clusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onUpdate(tenantId, | 264 | clusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onUpdate(tenantId, |
265 | new DeviceId(entityId.getId()), DataConstants.SHARED_SCOPE, new ArrayList<>(attributes)) | 265 | new DeviceId(entityId.getId()), DataConstants.SHARED_SCOPE, new ArrayList<>(attributes)) |
@@ -269,10 +269,10 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | @@ -269,10 +269,10 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene | ||
269 | callback.onSuccess(); | 269 | callback.onSuccess(); |
270 | } | 270 | } |
271 | 271 | ||
272 | - private void updateDeviceInactivityTimeout(EntityId entityId, List<? extends KvEntry> kvEntries) { | 272 | + private void updateDeviceInactivityTimeout(TenantId tenantId, EntityId entityId, List<? extends KvEntry> kvEntries) { |
273 | for (KvEntry kvEntry : kvEntries) { | 273 | for (KvEntry kvEntry : kvEntries) { |
274 | if (kvEntry.getKey().equals(DefaultDeviceStateService.INACTIVITY_TIMEOUT)) { | 274 | if (kvEntry.getKey().equals(DefaultDeviceStateService.INACTIVITY_TIMEOUT)) { |
275 | - deviceStateService.onDeviceInactivityTimeoutUpdate(new DeviceId(entityId.getId()), kvEntry.getLongValue().orElse(0L)); | 275 | + deviceStateService.onDeviceInactivityTimeoutUpdate(tenantId, new DeviceId(entityId.getId()), kvEntry.getLongValue().orElse(0L)); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | } | 278 | } |
@@ -30,7 +30,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | @@ -30,7 +30,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | ||
30 | import org.thingsboard.server.common.msg.queue.TbCallback; | 30 | import org.thingsboard.server.common.msg.queue.TbCallback; |
31 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 31 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
32 | import org.thingsboard.server.queue.util.TbCoreComponent; | 32 | import org.thingsboard.server.queue.util.TbCoreComponent; |
33 | -import org.thingsboard.server.service.queue.TbClusterService; | 33 | +import org.thingsboard.server.cluster.TbClusterService; |
34 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; | 34 | import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; |
35 | import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; | 35 | import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; |
36 | 36 | ||
@@ -42,7 +42,6 @@ import java.util.Map; | @@ -42,7 +42,6 @@ import java.util.Map; | ||
42 | import java.util.Set; | 42 | import java.util.Set; |
43 | import java.util.concurrent.ConcurrentHashMap; | 43 | import java.util.concurrent.ConcurrentHashMap; |
44 | import java.util.concurrent.ExecutorService; | 44 | import java.util.concurrent.ExecutorService; |
45 | -import java.util.concurrent.Executors; | ||
46 | 45 | ||
47 | @Slf4j | 46 | @Slf4j |
48 | @TbCoreComponent | 47 | @TbCoreComponent |
@@ -20,15 +20,13 @@ import com.google.common.util.concurrent.Futures; | @@ -20,15 +20,13 @@ import com.google.common.util.concurrent.Futures; | ||
20 | import com.google.common.util.concurrent.ListenableFuture; | 20 | import com.google.common.util.concurrent.ListenableFuture; |
21 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | -import org.springframework.context.ApplicationListener; | ||
24 | -import org.springframework.context.event.EventListener; | ||
25 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 23 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
26 | import org.thingsboard.server.common.msg.queue.ServiceType; | 24 | import org.thingsboard.server.common.msg.queue.ServiceType; |
27 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 25 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
28 | import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; | 26 | import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; |
29 | import org.thingsboard.server.queue.discovery.PartitionService; | 27 | import org.thingsboard.server.queue.discovery.PartitionService; |
30 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; | 28 | import org.thingsboard.server.queue.discovery.TbApplicationEventListener; |
31 | -import org.thingsboard.server.service.queue.TbClusterService; | 29 | +import org.thingsboard.server.cluster.TbClusterService; |
32 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 30 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
33 | 31 | ||
34 | import javax.annotation.Nullable; | 32 | import javax.annotation.Nullable; |
@@ -46,7 +46,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; | @@ -46,7 +46,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; | ||
46 | import org.thingsboard.server.queue.discovery.PartitionService; | 46 | import org.thingsboard.server.queue.discovery.PartitionService; |
47 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; | 47 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; |
48 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | 48 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; |
49 | -import org.thingsboard.server.service.queue.TbClusterService; | 49 | +import org.thingsboard.server.cluster.TbClusterService; |
50 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; | 50 | import org.thingsboard.server.service.subscription.SubscriptionManagerService; |
51 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 51 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
52 | 52 |
@@ -45,7 +45,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; | @@ -45,7 +45,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; | ||
45 | import org.thingsboard.server.queue.discovery.PartitionService; | 45 | import org.thingsboard.server.queue.discovery.PartitionService; |
46 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; | 46 | import org.thingsboard.server.queue.usagestats.TbApiUsageClient; |
47 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | 47 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; |
48 | -import org.thingsboard.server.service.queue.TbClusterService; | 48 | +import org.thingsboard.server.cluster.TbClusterService; |
49 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; | 49 | import org.thingsboard.server.service.subscription.TbSubscriptionUtils; |
50 | 50 | ||
51 | import javax.annotation.Nullable; | 51 | import javax.annotation.Nullable; |
@@ -95,7 +95,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | @@ -95,7 +95,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; | ||
95 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | 95 | import org.thingsboard.server.service.apiusage.TbApiUsageStateService; |
96 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 96 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
97 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; | 97 | import org.thingsboard.server.service.profile.TbDeviceProfileCache; |
98 | -import org.thingsboard.server.service.queue.TbClusterService; | 98 | +import org.thingsboard.server.cluster.TbClusterService; |
99 | import org.thingsboard.server.service.resource.TbResourceService; | 99 | import org.thingsboard.server.service.resource.TbResourceService; |
100 | import org.thingsboard.server.service.state.DeviceStateService; | 100 | import org.thingsboard.server.service.state.DeviceStateService; |
101 | 101 | ||
@@ -265,9 +265,11 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -265,9 +265,11 @@ public class DefaultTransportApiService implements TransportApiService { | ||
265 | device.setCustomerId(gateway.getCustomerId()); | 265 | device.setCustomerId(gateway.getCustomerId()); |
266 | DeviceProfile deviceProfile = deviceProfileCache.findOrCreateDeviceProfile(gateway.getTenantId(), requestMsg.getDeviceType()); | 266 | DeviceProfile deviceProfile = deviceProfileCache.findOrCreateDeviceProfile(gateway.getTenantId(), requestMsg.getDeviceType()); |
267 | device.setDeviceProfileId(deviceProfile.getId()); | 267 | device.setDeviceProfileId(deviceProfile.getId()); |
268 | - device = deviceService.saveDevice(device); | 268 | + Device savedDevice = deviceService.saveDevice(device); |
269 | + tbClusterService.onDeviceUpdated(savedDevice, device); | ||
270 | + device = savedDevice; | ||
271 | + | ||
269 | relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); | 272 | relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); |
270 | - deviceStateService.onDeviceAdded(device); | ||
271 | 273 | ||
272 | TbMsgMetaData metaData = new TbMsgMetaData(); | 274 | TbMsgMetaData metaData = new TbMsgMetaData(); |
273 | CustomerId customerId = gateway.getCustomerId(); | 275 | CustomerId customerId = gateway.getCustomerId(); |
@@ -581,7 +583,7 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -581,7 +583,7 @@ public class DefaultTransportApiService implements TransportApiService { | ||
581 | device.setName(deviceName); | 583 | device.setName(deviceName); |
582 | device.setType("LwM2M"); | 584 | device.setType("LwM2M"); |
583 | device = deviceService.saveDevice(device); | 585 | device = deviceService.saveDevice(device); |
584 | - deviceStateService.onDeviceAdded(device); | 586 | + tbClusterService.onDeviceUpdated(device, null); |
585 | } | 587 | } |
586 | TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg = | 588 | TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg = |
587 | TransportProtos.LwM2MRegistrationResponseMsg.newBuilder() | 589 | TransportProtos.LwM2MRegistrationResponseMsg.newBuilder() |
@@ -588,6 +588,7 @@ transport: | @@ -588,6 +588,7 @@ transport: | ||
588 | bind_address: "${MQTT_BIND_ADDRESS:0.0.0.0}" | 588 | bind_address: "${MQTT_BIND_ADDRESS:0.0.0.0}" |
589 | bind_port: "${MQTT_BIND_PORT:1883}" | 589 | bind_port: "${MQTT_BIND_PORT:1883}" |
590 | timeout: "${MQTT_TIMEOUT:10000}" | 590 | timeout: "${MQTT_TIMEOUT:10000}" |
591 | + msg_queue_size_per_device_limit: "${MQTT_MSG_QUEUE_SIZE_PER_DEVICE_LIMIT:100}" # messages await in the queue before device connected state. This limit works on low level before TenantProfileLimits mechanism | ||
591 | netty: | 592 | netty: |
592 | leak_detector_level: "${NETTY_LEAK_DETECTOR_LVL:DISABLED}" | 593 | leak_detector_level: "${NETTY_LEAK_DETECTOR_LVL:DISABLED}" |
593 | boss_group_thread_count: "${NETTY_BOSS_GROUP_THREADS:1}" | 594 | boss_group_thread_count: "${NETTY_BOSS_GROUP_THREADS:1}" |
@@ -747,6 +748,8 @@ queue: | @@ -747,6 +748,8 @@ queue: | ||
747 | compression.type: "${TB_KAFKA_COMPRESSION_TYPE:none}" # none or gzip | 748 | compression.type: "${TB_KAFKA_COMPRESSION_TYPE:none}" # none or gzip |
748 | batch.size: "${TB_KAFKA_BATCH_SIZE:16384}" | 749 | batch.size: "${TB_KAFKA_BATCH_SIZE:16384}" |
749 | linger.ms: "${TB_KAFKA_LINGER_MS:1}" | 750 | linger.ms: "${TB_KAFKA_LINGER_MS:1}" |
751 | + max.request.size: "${TB_KAFKA_MAX_REQUEST_SIZE:1048576}" | ||
752 | + max.in.flight.requests.per.connection: "${TB_KAFKA_MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION:5}" | ||
750 | buffer.memory: "${TB_BUFFER_MEMORY:33554432}" | 753 | buffer.memory: "${TB_BUFFER_MEMORY:33554432}" |
751 | replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}" | 754 | replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}" |
752 | max_poll_interval_ms: "${TB_QUEUE_KAFKA_MAX_POLL_INTERVAL_MS:300000}" | 755 | max_poll_interval_ms: "${TB_QUEUE_KAFKA_MAX_POLL_INTERVAL_MS:300000}" |
@@ -763,7 +766,11 @@ queue: | @@ -763,7 +766,11 @@ queue: | ||
763 | tb_ota_package: | 766 | tb_ota_package: |
764 | - key: max.poll.records | 767 | - key: max.poll.records |
765 | value: 10 | 768 | value: 10 |
766 | - other: | 769 | + other: # In this section you can specify custom parameters for Kafka consumer/producer and expose the env variables to configure outside |
770 | + - key: "request.timeout.ms" # refer to https://docs.confluent.io/platform/current/installation/configuration/producer-configs.html#producerconfigs_request.timeout.ms | ||
771 | + value: "${TB_QUEUE_KAFKA_REQUEST_TIMEOUT_MS:30000}" # (30 seconds) | ||
772 | + - key: "session.timeout.ms" # refer to https://docs.confluent.io/platform/current/installation/configuration/consumer-configs.html#consumerconfigs_session.timeout.ms | ||
773 | + value: "${TB_QUEUE_KAFKA_SESSION_TIMEOUT_MS:10000}" # (10 seconds) | ||
767 | topic-properties: | 774 | topic-properties: |
768 | rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" | 775 | rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" |
769 | core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" | 776 | core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" |
@@ -17,6 +17,7 @@ package org.thingsboard.server.controller; | @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | +import org.awaitility.Awaitility; | ||
20 | import org.junit.After; | 21 | import org.junit.After; |
21 | import org.junit.Assert; | 22 | import org.junit.Assert; |
22 | import org.junit.Before; | 23 | import org.junit.Before; |
@@ -28,13 +29,14 @@ import org.thingsboard.server.common.data.asset.Asset; | @@ -28,13 +29,14 @@ import org.thingsboard.server.common.data.asset.Asset; | ||
28 | import org.thingsboard.server.common.data.edge.Edge; | 29 | import org.thingsboard.server.common.data.edge.Edge; |
29 | import org.thingsboard.server.common.data.edge.EdgeEvent; | 30 | import org.thingsboard.server.common.data.edge.EdgeEvent; |
30 | import org.thingsboard.server.common.data.edge.EdgeEventType; | 31 | import org.thingsboard.server.common.data.edge.EdgeEventType; |
31 | -import org.thingsboard.server.common.data.id.TenantId; | 32 | +import org.thingsboard.server.common.data.id.EdgeId; |
32 | import org.thingsboard.server.common.data.page.PageData; | 33 | import org.thingsboard.server.common.data.page.PageData; |
33 | import org.thingsboard.server.common.data.page.TimePageLink; | 34 | import org.thingsboard.server.common.data.page.TimePageLink; |
34 | import org.thingsboard.server.common.data.relation.EntityRelation; | 35 | import org.thingsboard.server.common.data.relation.EntityRelation; |
35 | import org.thingsboard.server.common.data.security.Authority; | 36 | import org.thingsboard.server.common.data.security.Authority; |
36 | 37 | ||
37 | import java.util.List; | 38 | import java.util.List; |
39 | +import java.util.concurrent.TimeUnit; | ||
38 | 40 | ||
39 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | 41 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
40 | 42 | ||
@@ -83,34 +85,37 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | @@ -83,34 +85,37 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest { | ||
83 | Device device = constructDevice("TestDevice", "default"); | 85 | Device device = constructDevice("TestDevice", "default"); |
84 | Device savedDevice = doPost("/api/device", device, Device.class); | 86 | Device savedDevice = doPost("/api/device", device, Device.class); |
85 | 87 | ||
86 | - doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); | 88 | + final EdgeId edgeId = edge.getId(); |
89 | + doPost("/api/edge/" + edgeId.toString() + "/device/" + savedDevice.getId().toString(), Device.class); | ||
87 | 90 | ||
88 | Asset asset = constructAsset("TestAsset", "default"); | 91 | Asset asset = constructAsset("TestAsset", "default"); |
89 | Asset savedAsset = doPost("/api/asset", asset, Asset.class); | 92 | Asset savedAsset = doPost("/api/asset", asset, Asset.class); |
90 | 93 | ||
91 | - doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); | 94 | + doPost("/api/edge/" + edgeId.toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); |
92 | 95 | ||
93 | EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); | 96 | EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); |
94 | 97 | ||
95 | doPost("/api/relation", relation); | 98 | doPost("/api/relation", relation); |
96 | 99 | ||
97 | - // wait while edge event for the relation entity persisted to DB | ||
98 | - Thread.sleep(100); | ||
99 | - List<EdgeEvent> edgeEvents; | ||
100 | - int attempt = 1; | ||
101 | - do { | ||
102 | - edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", | ||
103 | - new TypeReference<PageData<EdgeEvent>>() {}, new TimePageLink(4)).getData(); | ||
104 | - attempt++; | ||
105 | - Thread.sleep(100); | ||
106 | - } while (edgeEvents.size() != 4 && attempt < 5); | ||
107 | - Assert.assertEquals(4, edgeEvents.size()); | 100 | + Awaitility.await() |
101 | + .atMost(30, TimeUnit.SECONDS) | ||
102 | + .until(() -> { | ||
103 | + List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId); | ||
104 | + return edgeEvents.size() == 4; | ||
105 | + }); | ||
106 | + List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId); | ||
108 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RULE_CHAIN.equals(ee.getType()))); | 107 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RULE_CHAIN.equals(ee.getType()))); |
109 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.DEVICE.equals(ee.getType()))); | 108 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.DEVICE.equals(ee.getType()))); |
110 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.ASSET.equals(ee.getType()))); | 109 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.ASSET.equals(ee.getType()))); |
111 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RELATION.equals(ee.getType()))); | 110 | Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RELATION.equals(ee.getType()))); |
112 | } | 111 | } |
113 | 112 | ||
113 | + private List<EdgeEvent> findEdgeEvents(EdgeId edgeId) throws Exception { | ||
114 | + return doGetTypedWithTimePageLink("/api/edge/" + edgeId.toString() + "/events?", | ||
115 | + new TypeReference<PageData<EdgeEvent>>() { | ||
116 | + }, new TimePageLink(10)).getData(); | ||
117 | + } | ||
118 | + | ||
114 | private Device constructDevice(String name, String type) { | 119 | private Device constructDevice(String name, String type) { |
115 | Device device = new Device(); | 120 | Device device = new Device(); |
116 | device.setName(name); | 121 | device.setName(name); |
@@ -27,6 +27,7 @@ import com.google.protobuf.InvalidProtocolBufferException; | @@ -27,6 +27,7 @@ import com.google.protobuf.InvalidProtocolBufferException; | ||
27 | import com.google.protobuf.MessageLite; | 27 | import com.google.protobuf.MessageLite; |
28 | import lombok.extern.slf4j.Slf4j; | 28 | import lombok.extern.slf4j.Slf4j; |
29 | import org.apache.commons.lang3.RandomStringUtils; | 29 | import org.apache.commons.lang3.RandomStringUtils; |
30 | +import org.awaitility.Awaitility; | ||
30 | import org.junit.After; | 31 | import org.junit.After; |
31 | import org.junit.Assert; | 32 | import org.junit.Assert; |
32 | import org.junit.Before; | 33 | import org.junit.Before; |
@@ -114,7 +115,7 @@ import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; | @@ -114,7 +115,7 @@ import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; | ||
114 | import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; | 115 | import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; |
115 | import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; | 116 | import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; |
116 | import org.thingsboard.server.gen.transport.TransportProtos; | 117 | import org.thingsboard.server.gen.transport.TransportProtos; |
117 | -import org.thingsboard.server.service.queue.TbClusterService; | 118 | +import org.thingsboard.server.cluster.TbClusterService; |
118 | 119 | ||
119 | import java.util.ArrayList; | 120 | import java.util.ArrayList; |
120 | import java.util.List; | 121 | import java.util.List; |
@@ -126,6 +127,7 @@ import java.util.UUID; | @@ -126,6 +127,7 @@ import java.util.UUID; | ||
126 | import java.util.concurrent.TimeUnit; | 127 | import java.util.concurrent.TimeUnit; |
127 | 128 | ||
128 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | 129 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
130 | +import static org.thingsboard.server.service.edge.rpc.EdgeProtoUtils.getStringValue; | ||
129 | 131 | ||
130 | @Slf4j | 132 | @Slf4j |
131 | abstract public class BaseEdgeTest extends AbstractControllerTest { | 133 | abstract public class BaseEdgeTest extends AbstractControllerTest { |
@@ -648,7 +650,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -648,7 +650,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
648 | Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); | 650 | Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); |
649 | Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); | 651 | Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); |
650 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); | 652 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); |
651 | - Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); | 653 | + Assert.assertEquals(relationUpdateMsg.getTypeGroup().getValue(), relation.getTypeGroup().name()); |
652 | 654 | ||
653 | // 2 | 655 | // 2 |
654 | edgeImitator.expectMessageAmount(1); | 656 | edgeImitator.expectMessageAmount(1); |
@@ -672,7 +674,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -672,7 +674,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
672 | Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); | 674 | Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); |
673 | Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); | 675 | Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); |
674 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); | 676 | Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); |
675 | - Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); | 677 | + Assert.assertEquals(relationUpdateMsg.getTypeGroup().getValue(), relation.getTypeGroup().name()); |
676 | 678 | ||
677 | log.info("Relations tested successfully"); | 679 | log.info("Relations tested successfully"); |
678 | } | 680 | } |
@@ -730,7 +732,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -730,7 +732,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
730 | edgeImitator.expectMessageAmount(1); | 732 | edgeImitator.expectMessageAmount(1); |
731 | doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) | 733 | doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) |
732 | .andExpect(status().isOk()); | 734 | .andExpect(status().isOk()); |
733 | - Assert.assertFalse(edgeImitator.waitForMessages(1)); | 735 | + Assert.assertTrue(edgeImitator.waitForMessages(1)); |
736 | + latestMessage = edgeImitator.getLatestMessage(); | ||
737 | + Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); | ||
738 | + alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; | ||
739 | + Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); | ||
740 | + Assert.assertEquals(alarmUpdateMsg.getType(), savedAlarm.getType()); | ||
741 | + Assert.assertEquals(alarmUpdateMsg.getName(), savedAlarm.getName()); | ||
742 | + Assert.assertEquals(alarmUpdateMsg.getOriginatorName(), device.getName()); | ||
743 | + Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); | ||
734 | 744 | ||
735 | log.info("Alarms tested successfully"); | 745 | log.info("Alarms tested successfully"); |
736 | } | 746 | } |
@@ -900,9 +910,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -900,9 +910,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
900 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); | 910 | Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, widgetTypeUpdateMsg.getMsgType()); |
901 | Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); | 911 | Assert.assertEquals(widgetTypeUpdateMsg.getIdMSB(), savedWidgetType.getUuidId().getMostSignificantBits()); |
902 | Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); | 912 | Assert.assertEquals(widgetTypeUpdateMsg.getIdLSB(), savedWidgetType.getUuidId().getLeastSignificantBits()); |
903 | - Assert.assertEquals(widgetTypeUpdateMsg.getAlias(), savedWidgetType.getAlias()); | ||
904 | - Assert.assertEquals(widgetTypeUpdateMsg.getName(), savedWidgetType.getName()); | ||
905 | - Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson()), savedWidgetType.getDescriptor()); | 913 | + Assert.assertEquals(widgetTypeUpdateMsg.getAlias().getValue(), savedWidgetType.getAlias()); |
914 | + Assert.assertEquals(widgetTypeUpdateMsg.getName().getValue(), savedWidgetType.getName()); | ||
915 | + Assert.assertEquals(JacksonUtil.toJsonNode(widgetTypeUpdateMsg.getDescriptorJson().getValue()), savedWidgetType.getDescriptor()); | ||
906 | 916 | ||
907 | // 3 | 917 | // 3 |
908 | edgeImitator.expectMessageAmount(1); | 918 | edgeImitator.expectMessageAmount(1); |
@@ -939,7 +949,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -939,7 +949,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
939 | String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; | 949 | String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; |
940 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); | 950 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); |
941 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); | 951 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); |
942 | - edgeEventService.saveAsync(edgeEvent); | 952 | + edgeEventService.save(edgeEvent); |
943 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 953 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
944 | Assert.assertTrue(edgeImitator.waitForMessages()); | 954 | Assert.assertTrue(edgeImitator.waitForMessages()); |
945 | 955 | ||
@@ -978,7 +988,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -978,7 +988,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
978 | JsonNode attributesEntityData = mapper.readTree(attributesData); | 988 | JsonNode attributesEntityData = mapper.readTree(attributesData); |
979 | EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); | 989 | EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); |
980 | edgeImitator.expectMessageAmount(1); | 990 | edgeImitator.expectMessageAmount(1); |
981 | - edgeEventService.saveAsync(edgeEvent1); | 991 | + edgeEventService.save(edgeEvent1); |
982 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 992 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
983 | Assert.assertTrue(edgeImitator.waitForMessages()); | 993 | Assert.assertTrue(edgeImitator.waitForMessages()); |
984 | 994 | ||
@@ -1003,7 +1013,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1003,7 +1013,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1003 | JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); | 1013 | JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); |
1004 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); | 1014 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); |
1005 | edgeImitator.expectMessageAmount(1); | 1015 | edgeImitator.expectMessageAmount(1); |
1006 | - edgeEventService.saveAsync(edgeEvent); | 1016 | + edgeEventService.save(edgeEvent); |
1007 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1017 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
1008 | Assert.assertTrue(edgeImitator.waitForMessages()); | 1018 | Assert.assertTrue(edgeImitator.waitForMessages()); |
1009 | 1019 | ||
@@ -1028,7 +1038,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1028,7 +1038,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1028 | JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); | 1038 | JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); |
1029 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); | 1039 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); |
1030 | edgeImitator.expectMessageAmount(1); | 1040 | edgeImitator.expectMessageAmount(1); |
1031 | - edgeEventService.saveAsync(edgeEvent); | 1041 | + edgeEventService.save(edgeEvent); |
1032 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1042 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
1033 | Assert.assertTrue(edgeImitator.waitForMessages()); | 1043 | Assert.assertTrue(edgeImitator.waitForMessages()); |
1034 | 1044 | ||
@@ -1062,7 +1072,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1062,7 +1072,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1062 | 1072 | ||
1063 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); | 1073 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); |
1064 | edgeImitator.expectMessageAmount(1); | 1074 | edgeImitator.expectMessageAmount(1); |
1065 | - edgeEventService.saveAsync(edgeEvent); | 1075 | + edgeEventService.save(edgeEvent); |
1066 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1076 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
1067 | Assert.assertTrue(edgeImitator.waitForMessages()); | 1077 | Assert.assertTrue(edgeImitator.waitForMessages()); |
1068 | 1078 | ||
@@ -1088,7 +1098,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1088,7 +1098,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1088 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); | 1098 | JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); |
1089 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, | 1099 | EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, |
1090 | device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); | 1100 | device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); |
1091 | - edgeEventService.saveAsync(edgeEvent); | 1101 | + edgeEventService.save(edgeEvent); |
1092 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); | 1102 | clusterService.onEdgeEventUpdate(tenantId, edge.getId()); |
1093 | } | 1103 | } |
1094 | 1104 | ||
@@ -1202,7 +1212,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1202,7 +1212,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1202 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | 1212 | Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); |
1203 | DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | 1213 | DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; |
1204 | Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); | 1214 | Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); |
1205 | - Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName()); | 1215 | + Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName().getValue()); |
1206 | 1216 | ||
1207 | UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); | 1217 | UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); |
1208 | 1218 | ||
@@ -1269,7 +1279,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1269,7 +1279,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1269 | EntityId toEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getToEntityType(), toUUID); | 1279 | EntityId toEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getToEntityType(), toUUID); |
1270 | Assert.assertEquals(relation.getTo(), toEntityId); | 1280 | Assert.assertEquals(relation.getTo(), toEntityId); |
1271 | 1281 | ||
1272 | - Assert.assertEquals(relation.getTypeGroup().name(), relationUpdateMsg.getTypeGroup()); | 1282 | + Assert.assertEquals(relation.getTypeGroup().name(), relationUpdateMsg.getTypeGroup().getValue()); |
1273 | } | 1283 | } |
1274 | 1284 | ||
1275 | private void sendAlarm() throws Exception { | 1285 | private void sendAlarm() throws Exception { |
@@ -1348,15 +1358,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1348,15 +1358,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1348 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); | 1358 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); |
1349 | Assert.assertTrue(edgeImitator.waitForResponses()); | 1359 | Assert.assertTrue(edgeImitator.waitForResponses()); |
1350 | 1360 | ||
1351 | - int attempt = 0; | ||
1352 | - Map<String, List<Map<String, String>>> timeseries; | ||
1353 | - do { | ||
1354 | - timeseries = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, | ||
1355 | - new TypeReference<>() {}); | ||
1356 | - // Wait before device attributes saved to database before requesting them from controller | ||
1357 | - Thread.sleep(100); | ||
1358 | - attempt++; | ||
1359 | - } while (!timeseries.containsKey(timeseriesKey) || attempt < 10); | 1361 | + Awaitility.await() |
1362 | + .atMost(2, TimeUnit.SECONDS) | ||
1363 | + .until(() -> loadDeviceTimeseries(device, timeseriesKey).containsKey(timeseriesKey)); | ||
1364 | + | ||
1365 | + Map<String, List<Map<String, String>>> timeseries = loadDeviceTimeseries(device, timeseriesKey); | ||
1360 | Assert.assertTrue(timeseries.containsKey(timeseriesKey)); | 1366 | Assert.assertTrue(timeseries.containsKey(timeseriesKey)); |
1361 | Assert.assertEquals(1, timeseries.get(timeseriesKey).size()); | 1367 | Assert.assertEquals(1, timeseries.get(timeseriesKey).size()); |
1362 | Assert.assertEquals(timeseriesValue, timeseries.get(timeseriesKey).get(0).get("value")); | 1368 | Assert.assertEquals(timeseriesValue, timeseries.get(timeseriesKey).get(0).get("value")); |
@@ -1365,7 +1371,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1365,7 +1371,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1365 | Assert.assertEquals(1, attributes.size()); | 1371 | Assert.assertEquals(1, attributes.size()); |
1366 | Assert.assertEquals(attributes.get(0).get("key"), attributesKey); | 1372 | Assert.assertEquals(attributes.get(0).get("key"), attributesKey); |
1367 | Assert.assertEquals(attributes.get(0).get("value"), attributesValue); | 1373 | Assert.assertEquals(attributes.get(0).get("value"), attributesValue); |
1374 | + } | ||
1368 | 1375 | ||
1376 | + private Map<String, List<Map<String, String>>> loadDeviceTimeseries(Device device, String timeseriesKey) throws Exception { | ||
1377 | + return doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/values/timeseries?keys=" + timeseriesKey, | ||
1378 | + new TypeReference<>() {}); | ||
1369 | } | 1379 | } |
1370 | 1380 | ||
1371 | private void sendRelation() throws Exception { | 1381 | private void sendRelation() throws Exception { |
@@ -1381,7 +1391,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1381,7 +1391,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1381 | UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); | 1391 | UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); |
1382 | RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); | 1392 | RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); |
1383 | relationUpdateMsgBuilder.setType("test"); | 1393 | relationUpdateMsgBuilder.setType("test"); |
1384 | - relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); | 1394 | + relationUpdateMsgBuilder.setTypeGroup(getStringValue(RelationTypeGroup.COMMON.name())); |
1385 | relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); | 1395 | relationUpdateMsgBuilder.setToIdMSB(device1.getId().getId().getMostSignificantBits()); |
1386 | relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); | 1396 | relationUpdateMsgBuilder.setToIdLSB(device1.getId().getId().getLeastSignificantBits()); |
1387 | relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); | 1397 | relationUpdateMsgBuilder.setToEntityType(device1.getId().getEntityType().name()); |
@@ -1447,7 +1457,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | @@ -1447,7 +1457,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { | ||
1447 | edgeImitator.expectMessageAmount(1); | 1457 | edgeImitator.expectMessageAmount(1); |
1448 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | 1458 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1449 | Assert.assertTrue(edgeImitator.waitForResponses()); | 1459 | Assert.assertTrue(edgeImitator.waitForResponses()); |
1450 | - Assert.assertTrue(edgeImitator.waitForMessages());; | 1460 | + Assert.assertTrue(edgeImitator.waitForMessages()); |
1451 | 1461 | ||
1452 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | 1462 | AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
1453 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); | 1463 | Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); |
@@ -27,7 +27,7 @@ import org.thingsboard.server.dao.device.DeviceService; | @@ -27,7 +27,7 @@ import org.thingsboard.server.dao.device.DeviceService; | ||
27 | import org.thingsboard.server.dao.tenant.TenantService; | 27 | import org.thingsboard.server.dao.tenant.TenantService; |
28 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 28 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
29 | import org.thingsboard.server.queue.discovery.PartitionService; | 29 | import org.thingsboard.server.queue.discovery.PartitionService; |
30 | -import org.thingsboard.server.service.queue.TbClusterService; | 30 | +import org.thingsboard.server.cluster.TbClusterService; |
31 | 31 | ||
32 | import static org.hamcrest.CoreMatchers.is; | 32 | import static org.hamcrest.CoreMatchers.is; |
33 | import static org.hamcrest.MatcherAssert.assertThat; | 33 | import static org.hamcrest.MatcherAssert.assertThat; |
@@ -43,7 +43,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | @@ -43,7 +43,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | ||
43 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; | 43 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; |
44 | String deviceId = savedDevice.getId().getId().toString(); | 44 | String deviceId = savedDevice.getId().getId().toString(); |
45 | 45 | ||
46 | - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), | 46 | + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), |
47 | asyncContextTimeoutToUseRpcPlugin); | 47 | asyncContextTimeoutToUseRpcPlugin); |
48 | } | 48 | } |
49 | 49 | ||
@@ -52,7 +52,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | @@ -52,7 +52,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | ||
52 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; | 52 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; |
53 | String nonExistentDeviceId = Uuids.timeBased().toString(); | 53 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
54 | 54 | ||
55 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | 55 | + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, |
56 | status().isNotFound()); | 56 | status().isNotFound()); |
57 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | 57 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
58 | } | 58 | } |
@@ -62,7 +62,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | @@ -62,7 +62,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | ||
62 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; | 62 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; |
63 | String deviceId = savedDevice.getId().getId().toString(); | 63 | String deviceId = savedDevice.getId().getId().toString(); |
64 | 64 | ||
65 | - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), | 65 | + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), |
66 | asyncContextTimeoutToUseRpcPlugin); | 66 | asyncContextTimeoutToUseRpcPlugin); |
67 | } | 67 | } |
68 | 68 | ||
@@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab | ||
71 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; | 71 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; |
72 | String nonExistentDeviceId = Uuids.timeBased().toString(); | 72 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
73 | 73 | ||
74 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | 74 | + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, |
75 | status().isNotFound()); | 75 | status().isNotFound()); |
76 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | 76 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
77 | } | 77 | } |
@@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | @@ -71,7 +71,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | ||
71 | 71 | ||
72 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 72 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
73 | String deviceId = savedDevice.getId().getId().toString(); | 73 | String deviceId = savedDevice.getId().getId().toString(); |
74 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 74 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
75 | 75 | ||
76 | latch.await(3, TimeUnit.SECONDS); | 76 | latch.await(3, TimeUnit.SECONDS); |
77 | 77 | ||
@@ -99,14 +99,14 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | @@ -99,14 +99,14 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC | ||
99 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; | 99 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
100 | String deviceId = savedDevice.getId().getId().toString(); | 100 | String deviceId = savedDevice.getId().getId().toString(); |
101 | 101 | ||
102 | - String actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 102 | + String actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
103 | latch.await(3, TimeUnit.SECONDS); | 103 | latch.await(3, TimeUnit.SECONDS); |
104 | 104 | ||
105 | validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult); | 105 | validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult); |
106 | 106 | ||
107 | latch = new CountDownLatch(1); | 107 | latch = new CountDownLatch(1); |
108 | 108 | ||
109 | - actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 109 | + actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
110 | latch.await(3, TimeUnit.SECONDS); | 110 | latch.await(3, TimeUnit.SECONDS); |
111 | 111 | ||
112 | validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult); | 112 | validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult); |
@@ -27,6 +27,7 @@ import org.springframework.mock.web.MockMultipartFile; | @@ -27,6 +27,7 @@ import org.springframework.mock.web.MockMultipartFile; | ||
27 | import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; | 27 | import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; |
28 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | 28 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; |
29 | import org.thingsboard.common.util.JacksonUtil; | 29 | import org.thingsboard.common.util.JacksonUtil; |
30 | +import org.thingsboard.common.util.ThingsBoardThreadFactory; | ||
30 | import org.thingsboard.server.common.data.Device; | 31 | import org.thingsboard.server.common.data.Device; |
31 | import org.thingsboard.server.common.data.DeviceProfile; | 32 | import org.thingsboard.server.common.data.DeviceProfile; |
32 | import org.thingsboard.server.common.data.DeviceProfileProvisionType; | 33 | import org.thingsboard.server.common.data.DeviceProfileProvisionType; |
@@ -261,7 +262,7 @@ public class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { | @@ -261,7 +262,7 @@ public class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { | ||
261 | 262 | ||
262 | @Before | 263 | @Before |
263 | public void beforeTest() throws Exception { | 264 | public void beforeTest() throws Exception { |
264 | - executor = Executors.newScheduledThreadPool(10); | 265 | + executor = Executors.newScheduledThreadPool(10, ThingsBoardThreadFactory.forName("test-lwm2m-scheduled")); |
265 | loginTenantAdmin(); | 266 | loginTenantAdmin(); |
266 | 267 | ||
267 | String[] resources = new String[]{"1.xml", "2.xml", "3.xml", "5.xml", "9.xml"}; | 268 | String[] resources = new String[]{"1.xml", "2.xml", "3.xml", "5.xml", "9.xml"}; |
@@ -16,6 +16,8 @@ | @@ -16,6 +16,8 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m; | 16 | package org.thingsboard.server.transport.lwm2m; |
17 | 17 | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.junit.After; | ||
19 | import org.junit.Assert; | 21 | import org.junit.Assert; |
20 | import org.junit.Test; | 22 | import org.junit.Test; |
21 | import org.thingsboard.server.common.data.Device; | 23 | import org.thingsboard.server.common.data.Device; |
@@ -23,16 +25,18 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCr | @@ -23,16 +25,18 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCr | ||
23 | import org.thingsboard.server.common.data.kv.KvEntry; | 25 | import org.thingsboard.server.common.data.kv.KvEntry; |
24 | import org.thingsboard.server.common.data.kv.TsKvEntry; | 26 | import org.thingsboard.server.common.data.kv.TsKvEntry; |
25 | import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; | 27 | import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; |
26 | -import org.thingsboard.server.common.data.query.EntityKey; | ||
27 | -import org.thingsboard.server.common.data.query.EntityKeyType; | ||
28 | import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; | 28 | import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; |
29 | 29 | ||
30 | import java.util.Arrays; | 30 | import java.util.Arrays; |
31 | import java.util.Collections; | 31 | import java.util.Collections; |
32 | import java.util.Comparator; | 32 | import java.util.Comparator; |
33 | import java.util.List; | 33 | import java.util.List; |
34 | +import java.util.UUID; | ||
35 | +import java.util.concurrent.TimeUnit; | ||
34 | import java.util.stream.Collectors; | 36 | import java.util.stream.Collectors; |
35 | 37 | ||
38 | +import static org.awaitility.Awaitility.await; | ||
39 | +import static org.hamcrest.Matchers.is; | ||
36 | import static org.thingsboard.rest.client.utils.RestJsonConverter.toTimeseries; | 40 | import static org.thingsboard.rest.client.utils.RestJsonConverter.toTimeseries; |
37 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; | 41 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; |
38 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING; | 42 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING; |
@@ -43,8 +47,10 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDA | @@ -43,8 +47,10 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDA | ||
43 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; | 47 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; |
44 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED; | 48 | import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED; |
45 | 49 | ||
50 | +@Slf4j | ||
46 | public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | 51 | public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { |
47 | 52 | ||
53 | + public static final int TIMEOUT = 30; | ||
48 | private final String OTA_TRANSPORT_CONFIGURATION = "{\n" + | 54 | private final String OTA_TRANSPORT_CONFIGURATION = "{\n" + |
49 | " \"observeAttr\": {\n" + | 55 | " \"observeAttr\": {\n" + |
50 | " \"keyName\": {\n" + | 56 | " \"keyName\": {\n" + |
@@ -122,6 +128,15 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | @@ -122,6 +128,15 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | ||
122 | " \"type\": \"LWM2M\"\n" + | 128 | " \"type\": \"LWM2M\"\n" + |
123 | "}"; | 129 | "}"; |
124 | 130 | ||
131 | + LwM2MTestClient client = null; | ||
132 | + | ||
133 | + @After | ||
134 | + public void tearDown() { | ||
135 | + if (client != null) { | ||
136 | + client.destroy(); | ||
137 | + } | ||
138 | + } | ||
139 | + | ||
125 | @Test | 140 | @Test |
126 | public void testConnectAndObserveTelemetry() throws Exception { | 141 | public void testConnectAndObserveTelemetry() throws Exception { |
127 | NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); | 142 | NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); |
@@ -196,37 +211,68 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | @@ -196,37 +211,68 @@ public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { | ||
196 | } | 211 | } |
197 | } | 212 | } |
198 | 213 | ||
214 | + /** | ||
215 | + * This is the example how to use the AWAITILITY instead Thread.sleep() | ||
216 | + * Test will finish as fast as possible, but will await until TIMEOUT if a build machine is busy or slow | ||
217 | + * Check the detailed log output to learn how Awaitility polling the API and when exactly expected result appears | ||
218 | + * */ | ||
199 | @Test | 219 | @Test |
200 | public void testSoftwareUpdateByObject9() throws Exception { | 220 | public void testSoftwareUpdateByObject9() throws Exception { |
201 | - LwM2MTestClient client = null; | ||
202 | - try { | ||
203 | - createDeviceProfile(OTA_TRANSPORT_CONFIGURATION); | ||
204 | - NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); | ||
205 | - clientCredentials.setEndpoint("OTA_" + ENDPOINT); | ||
206 | - Device device = createDevice(clientCredentials); | ||
207 | - | ||
208 | - device.setSoftwareId(createSoftware().getId()); | ||
209 | - device = doPost("/api/device", device, Device.class); | 221 | + //given |
222 | + final List<OtaPackageUpdateStatus> expectedStatuses = Collections.unmodifiableList(Arrays.asList( | ||
223 | + QUEUED, INITIATED, DOWNLOADING, DOWNLOADING, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATED)); | ||
210 | 224 | ||
211 | - Thread.sleep(1000); | ||
212 | - | ||
213 | - client = new LwM2MTestClient(executor, "OTA_" + ENDPOINT); | ||
214 | - client.init(SECURITY, COAP_CONFIG); | ||
215 | - | ||
216 | - Thread.sleep(3000); | ||
217 | - | ||
218 | - List<TsKvEntry> ts = toTimeseries(doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/values/timeseries?orderBy=ASC&keys=sw_state&startTs=0&endTs=" + System.currentTimeMillis(), new TypeReference<>() { | ||
219 | - })); | ||
220 | - | ||
221 | - List<OtaPackageUpdateStatus> statuses = ts.stream().sorted(Comparator.comparingLong(TsKvEntry::getTs)).map(KvEntry::getValueAsString).map(OtaPackageUpdateStatus::valueOf).collect(Collectors.toList()); | 225 | + createDeviceProfile(OTA_TRANSPORT_CONFIGURATION); |
226 | + NoSecClientCredentials clientCredentials = new NoSecClientCredentials(); | ||
227 | + clientCredentials.setEndpoint("OTA_" + ENDPOINT); | ||
228 | + final Device device = createDevice(clientCredentials); | ||
229 | + device.setSoftwareId(createSoftware().getId()); | ||
230 | + | ||
231 | + log.warn("Saving by API " + device); | ||
232 | + final Device savedDevice = doPost("/api/device", device, Device.class); | ||
233 | + Assert.assertNotNull(savedDevice); | ||
234 | + log.warn("Device saved by API {}", savedDevice); | ||
235 | + | ||
236 | + log.warn("AWAIT atMost {} SECONDS on get device by API...", TIMEOUT); | ||
237 | + await() | ||
238 | + .atMost(TIMEOUT, TimeUnit.SECONDS) | ||
239 | + .until(() -> getDeviceFromAPI(device.getId().getId()), is(savedDevice)); | ||
240 | + log.warn("Got device by API."); | ||
241 | + | ||
242 | + //when | ||
243 | + log.warn("Init the client..."); | ||
244 | + client = new LwM2MTestClient(executor, "OTA_" + ENDPOINT); | ||
245 | + client.init(SECURITY, COAP_CONFIG); | ||
246 | + log.warn("Init done"); | ||
247 | + | ||
248 | + log.warn("AWAIT atMost {} SECONDS on timeseries List<TsKvEntry> by API with list size {}...", TIMEOUT, expectedStatuses.size()); | ||
249 | + await() | ||
250 | + .atMost(30, TimeUnit.SECONDS) | ||
251 | + .until(() -> getSwStateTelemetryFromAPI(device.getId().getId()) | ||
252 | + .size(), is(expectedStatuses.size())); | ||
253 | + log.warn("Got an expected await condition!"); | ||
254 | + | ||
255 | + //then | ||
256 | + log.warn("Fetching ts for the final asserts"); | ||
257 | + List<TsKvEntry> ts = getSwStateTelemetryFromAPI(device.getId().getId()); | ||
258 | + log.warn("Got an ts {}", ts); | ||
259 | + | ||
260 | + List<OtaPackageUpdateStatus> statuses = ts.stream().sorted(Comparator.comparingLong(TsKvEntry::getTs)).map(KvEntry::getValueAsString).map(OtaPackageUpdateStatus::valueOf).collect(Collectors.toList()); | ||
261 | + log.warn("Converted ts to statuses {}", statuses); | ||
262 | + | ||
263 | + Assert.assertEquals(expectedStatuses, statuses); | ||
264 | + } | ||
222 | 265 | ||
223 | - List<OtaPackageUpdateStatus> expectedStatuses = Arrays.asList(QUEUED, INITIATED, DOWNLOADING, DOWNLOADING, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATED); | 266 | + private Device getDeviceFromAPI(UUID deviceId) throws Exception { |
267 | + final Device device = doGet("/api/device/" + deviceId, Device.class); | ||
268 | + log.warn("Fetched device by API for deviceId {}, device is {}", deviceId, device); | ||
269 | + return device; | ||
270 | + } | ||
224 | 271 | ||
225 | - Assert.assertEquals(expectedStatuses, statuses); | ||
226 | - } finally { | ||
227 | - if (client != null) { | ||
228 | - client.destroy(); | ||
229 | - } | ||
230 | - } | 272 | + private List<TsKvEntry> getSwStateTelemetryFromAPI(UUID deviceId) throws Exception { |
273 | + final List<TsKvEntry> tsKvEntries = toTimeseries(doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?orderBy=ASC&keys=sw_state&startTs=0&endTs=" + System.currentTimeMillis(), new TypeReference<>() { | ||
274 | + })); | ||
275 | + log.warn("Fetched telemetry by API for deviceId {}, list size {}, tsKvEntries {}", deviceId, tsKvEntries.size(), tsKvEntries); | ||
276 | + return tsKvEntries; | ||
231 | } | 277 | } |
232 | } | 278 | } |
@@ -46,7 +46,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | @@ -46,7 +46,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | ||
46 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; | 46 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"24\",\"value\": 1},\"timeout\": 6000}"; |
47 | String deviceId = savedDevice.getId().getId().toString(); | 47 | String deviceId = savedDevice.getId().getId().toString(); |
48 | 48 | ||
49 | - doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(409), | 49 | + doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(504), |
50 | asyncContextTimeoutToUseRpcPlugin); | 50 | asyncContextTimeoutToUseRpcPlugin); |
51 | } | 51 | } |
52 | 52 | ||
@@ -55,7 +55,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | @@ -55,7 +55,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | ||
55 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; | 55 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"25\",\"value\": 1}}"; |
56 | String nonExistentDeviceId = Uuids.timeBased().toString(); | 56 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
57 | 57 | ||
58 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | 58 | + String result = doPostAsync("/api/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, |
59 | status().isNotFound()); | 59 | status().isNotFound()); |
60 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | 60 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
61 | } | 61 | } |
@@ -65,7 +65,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | @@ -65,7 +65,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | ||
65 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; | 65 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"27\",\"value\": 1},\"timeout\": 6000}"; |
66 | String deviceId = savedDevice.getId().getId().toString(); | 66 | String deviceId = savedDevice.getId().getId().toString(); |
67 | 67 | ||
68 | - doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(409), | 68 | + doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(504), |
69 | asyncContextTimeoutToUseRpcPlugin); | 69 | asyncContextTimeoutToUseRpcPlugin); |
70 | } | 70 | } |
71 | 71 | ||
@@ -74,7 +74,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | @@ -74,7 +74,7 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab | ||
74 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; | 74 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"28\",\"value\": 1}}"; |
75 | String nonExistentDeviceId = Uuids.timeBased().toString(); | 75 | String nonExistentDeviceId = Uuids.timeBased().toString(); |
76 | 76 | ||
77 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | 77 | + String result = doPostAsync("/api/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, |
78 | status().isNotFound()); | 78 | status().isNotFound()); |
79 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | 79 | Assert.assertEquals(AccessValidator.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); |
80 | } | 80 | } |
@@ -69,7 +69,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | @@ -69,7 +69,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | ||
69 | 69 | ||
70 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 70 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
71 | String deviceId = savedDevice.getId().getId().toString(); | 71 | String deviceId = savedDevice.getId().getId().toString(); |
72 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 72 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
73 | Assert.assertTrue(StringUtils.isEmpty(result)); | 73 | Assert.assertTrue(StringUtils.isEmpty(result)); |
74 | latch.await(3, TimeUnit.SECONDS); | 74 | latch.await(3, TimeUnit.SECONDS); |
75 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); | 75 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); |
@@ -95,7 +95,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | @@ -95,7 +95,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | ||
95 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; | 95 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
96 | String deviceId = savedDevice.getId().getId().toString(); | 96 | String deviceId = savedDevice.getId().getId().toString(); |
97 | 97 | ||
98 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 98 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
99 | String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; | 99 | String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; |
100 | latch.await(3, TimeUnit.SECONDS); | 100 | latch.await(3, TimeUnit.SECONDS); |
101 | Assert.assertEquals(expected, result); | 101 | Assert.assertEquals(expected, result); |
@@ -130,7 +130,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | @@ -130,7 +130,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | ||
130 | 130 | ||
131 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; | 131 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; |
132 | String deviceId = savedDevice.getId().getId().toString(); | 132 | String deviceId = savedDevice.getId().getId().toString(); |
133 | - String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 133 | + String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
134 | Assert.assertTrue(StringUtils.isEmpty(result)); | 134 | Assert.assertTrue(StringUtils.isEmpty(result)); |
135 | latch.await(3, TimeUnit.SECONDS); | 135 | latch.await(3, TimeUnit.SECONDS); |
136 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); | 136 | assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); |
@@ -156,7 +156,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | @@ -156,7 +156,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM | ||
156 | 156 | ||
157 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; | 157 | String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; |
158 | String deviceId = savedDevice.getId().getId().toString(); | 158 | String deviceId = savedDevice.getId().getId().toString(); |
159 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 159 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
160 | latch.await(3, TimeUnit.SECONDS); | 160 | latch.await(3, TimeUnit.SECONDS); |
161 | String expected = "{\"success\":true}"; | 161 | String expected = "{\"success\":true}"; |
162 | assertEquals(expected, result); | 162 | assertEquals(expected, result); |
@@ -131,7 +131,7 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | @@ -131,7 +131,7 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst | ||
131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; | 131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; |
132 | String deviceId = savedDevice.getId().getId().toString(); | 132 | String deviceId = savedDevice.getId().getId().toString(); |
133 | 133 | ||
134 | - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | 134 | + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); |
135 | String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; | 135 | String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; |
136 | latch.await(3, TimeUnit.SECONDS); | 136 | latch.await(3, TimeUnit.SECONDS); |
137 | Assert.assertEquals(expected, result); | 137 | Assert.assertEquals(expected, result); |
common/cluster-api/pom.xml
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2021 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + <parent> | ||
22 | + <groupId>org.thingsboard</groupId> | ||
23 | + <version>3.3.0-SNAPSHOT</version> | ||
24 | + <artifactId>common</artifactId> | ||
25 | + </parent> | ||
26 | + <groupId>org.thingsboard.common</groupId> | ||
27 | + <artifactId>cluster-api</artifactId> | ||
28 | + <packaging>jar</packaging> | ||
29 | + | ||
30 | + <name>Thingsboard Server Common Cluster API</name> | ||
31 | + <url>https://thingsboard.io</url> | ||
32 | + | ||
33 | + <properties> | ||
34 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
35 | + <main.dir>${basedir}/../..</main.dir> | ||
36 | + </properties> | ||
37 | + | ||
38 | + <dependencies> | ||
39 | + <dependency> | ||
40 | + <groupId>org.thingsboard.common</groupId> | ||
41 | + <artifactId>data</artifactId> | ||
42 | + </dependency> | ||
43 | + <dependency> | ||
44 | + <groupId>org.thingsboard.common</groupId> | ||
45 | + <artifactId>message</artifactId> | ||
46 | + </dependency> | ||
47 | + <dependency> | ||
48 | + <groupId>org.thingsboard.common</groupId> | ||
49 | + <artifactId>stats</artifactId> | ||
50 | + </dependency> | ||
51 | + <dependency> | ||
52 | + <groupId>com.google.guava</groupId> | ||
53 | + <artifactId>guava</artifactId> | ||
54 | + </dependency> | ||
55 | + <dependency> | ||
56 | + <groupId>javax.annotation</groupId> | ||
57 | + <artifactId>javax.annotation-api</artifactId> | ||
58 | + </dependency> | ||
59 | + <dependency> | ||
60 | + <groupId>com.github.fge</groupId> | ||
61 | + <artifactId>json-schema-validator</artifactId> | ||
62 | + </dependency> | ||
63 | + <dependency> | ||
64 | + <groupId>org.slf4j</groupId> | ||
65 | + <artifactId>slf4j-api</artifactId> | ||
66 | + </dependency> | ||
67 | + <dependency> | ||
68 | + <groupId>org.slf4j</groupId> | ||
69 | + <artifactId>log4j-over-slf4j</artifactId> | ||
70 | + </dependency> | ||
71 | + <dependency> | ||
72 | + <groupId>ch.qos.logback</groupId> | ||
73 | + <artifactId>logback-core</artifactId> | ||
74 | + </dependency> | ||
75 | + <dependency> | ||
76 | + <groupId>ch.qos.logback</groupId> | ||
77 | + <artifactId>logback-classic</artifactId> | ||
78 | + </dependency> | ||
79 | + <dependency> | ||
80 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
81 | + <artifactId>jackson-databind</artifactId> | ||
82 | + </dependency> | ||
83 | + <dependency> | ||
84 | + <groupId>org.springframework.boot</groupId> | ||
85 | + <artifactId>spring-boot-autoconfigure</artifactId> | ||
86 | + <scope>provided</scope> | ||
87 | + </dependency> | ||
88 | + <dependency> | ||
89 | + <groupId>com.datastax.oss</groupId> | ||
90 | + <artifactId>java-driver-core</artifactId> | ||
91 | + <scope>provided</scope> | ||
92 | + </dependency> | ||
93 | + <dependency> | ||
94 | + <groupId>io.dropwizard.metrics</groupId> | ||
95 | + <artifactId>metrics-jmx</artifactId> | ||
96 | + <scope>provided</scope> | ||
97 | + </dependency> | ||
98 | + <dependency> | ||
99 | + <groupId>org.apache.commons</groupId> | ||
100 | + <artifactId>commons-lang3</artifactId> | ||
101 | + <scope>provided</scope> | ||
102 | + </dependency> | ||
103 | + <dependency> | ||
104 | + <groupId>junit</groupId> | ||
105 | + <artifactId>junit</artifactId> | ||
106 | + <scope>test</scope> | ||
107 | + </dependency> | ||
108 | + <dependency> | ||
109 | + <groupId>org.mockito</groupId> | ||
110 | + <artifactId>mockito-core</artifactId> | ||
111 | + <scope>test</scope> | ||
112 | + </dependency> | ||
113 | + </dependencies> | ||
114 | + | ||
115 | + <build> | ||
116 | + <plugins> | ||
117 | + <plugin> | ||
118 | + <groupId>org.xolstice.maven.plugins</groupId> | ||
119 | + <artifactId>protobuf-maven-plugin</artifactId> | ||
120 | + </plugin> | ||
121 | + <plugin> | ||
122 | + <groupId>org.apache.maven.plugins</groupId> | ||
123 | + <artifactId>maven-source-plugin</artifactId> | ||
124 | + <executions> | ||
125 | + <execution> | ||
126 | + <id>attach-sources</id> | ||
127 | + <goals> | ||
128 | + <goal>jar</goal> | ||
129 | + </goals> | ||
130 | + </execution> | ||
131 | + </executions> | ||
132 | + </plugin> | ||
133 | + <plugin> | ||
134 | + <groupId>org.apache.maven.plugins</groupId> | ||
135 | + <artifactId>maven-deploy-plugin</artifactId> | ||
136 | + <configuration> | ||
137 | + <skip>false</skip> | ||
138 | + </configuration> | ||
139 | + </plugin> | ||
140 | + </plugins> | ||
141 | + </build> | ||
142 | + | ||
143 | + | ||
144 | +</project> |
common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java
renamed from
application/src/main/java/org/thingsboard/server/service/queue/TbClusterService.java
@@ -13,26 +13,29 @@ | @@ -13,26 +13,29 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.service.queue; | 16 | +package org.thingsboard.server.cluster; |
17 | 17 | ||
18 | -import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; | 18 | +import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
19 | +import org.thingsboard.server.common.data.edge.EdgeEventType; | ||
20 | +import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; | ||
19 | import org.thingsboard.server.common.data.ApiUsageState; | 21 | import org.thingsboard.server.common.data.ApiUsageState; |
20 | import org.thingsboard.server.common.data.Device; | 22 | import org.thingsboard.server.common.data.Device; |
21 | import org.thingsboard.server.common.data.DeviceProfile; | 23 | import org.thingsboard.server.common.data.DeviceProfile; |
22 | import org.thingsboard.server.common.data.TbResource; | 24 | import org.thingsboard.server.common.data.TbResource; |
23 | import org.thingsboard.server.common.data.Tenant; | 25 | import org.thingsboard.server.common.data.Tenant; |
24 | import org.thingsboard.server.common.data.TenantProfile; | 26 | import org.thingsboard.server.common.data.TenantProfile; |
27 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
25 | import org.thingsboard.server.common.data.id.EdgeId; | 28 | import org.thingsboard.server.common.data.id.EdgeId; |
26 | import org.thingsboard.server.common.data.id.EntityId; | 29 | import org.thingsboard.server.common.data.id.EntityId; |
27 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
28 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | 31 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
29 | import org.thingsboard.server.common.msg.TbMsg; | 32 | import org.thingsboard.server.common.msg.TbMsg; |
30 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | 33 | import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
34 | +import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; | ||
31 | import org.thingsboard.server.gen.transport.TransportProtos; | 35 | import org.thingsboard.server.gen.transport.TransportProtos; |
32 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; | 36 | import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; |
33 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; | 37 | import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; |
34 | import org.thingsboard.server.queue.TbQueueCallback; | 38 | import org.thingsboard.server.queue.TbQueueCallback; |
35 | -import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; | ||
36 | 39 | ||
37 | import java.util.UUID; | 40 | import java.util.UUID; |
38 | 41 | ||
@@ -54,7 +57,7 @@ public interface TbClusterService { | @@ -54,7 +57,7 @@ public interface TbClusterService { | ||
54 | 57 | ||
55 | void pushNotificationToTransport(String targetServiceId, ToTransportMsg response, TbQueueCallback callback); | 58 | void pushNotificationToTransport(String targetServiceId, ToTransportMsg response, TbQueueCallback callback); |
56 | 59 | ||
57 | - void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state); | 60 | + void broadcastEntityStateChangeEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state); |
58 | 61 | ||
59 | void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback); | 62 | void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback); |
60 | 63 | ||
@@ -70,7 +73,7 @@ public interface TbClusterService { | @@ -70,7 +73,7 @@ public interface TbClusterService { | ||
70 | 73 | ||
71 | void onApiStateChange(ApiUsageState apiUsageState, TbQueueCallback callback); | 74 | void onApiStateChange(ApiUsageState apiUsageState, TbQueueCallback callback); |
72 | 75 | ||
73 | - void onDeviceChange(Device device, TbQueueCallback callback); | 76 | + void onDeviceUpdated(Device device, Device old); |
74 | 77 | ||
75 | void onDeviceDeleted(Device device, TbQueueCallback callback); | 78 | void onDeviceDeleted(Device device, TbQueueCallback callback); |
76 | 79 | ||
@@ -79,4 +82,6 @@ public interface TbClusterService { | @@ -79,4 +82,6 @@ public interface TbClusterService { | ||
79 | void onResourceDeleted(TbResource resource, TbQueueCallback callback); | 82 | void onResourceDeleted(TbResource resource, TbQueueCallback callback); |
80 | 83 | ||
81 | void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId); | 84 | void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId); |
85 | + | ||
86 | + void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action); | ||
82 | } | 87 | } |
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueAdmin.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueAdmin.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueCallback.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueCallback.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueConsumer.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueConsumer.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueHandler.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueHandler.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueMsg.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueMsg.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueMsgDecoder.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueMsgDecoder.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueMsgHeaders.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueMsgHeaders.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueMsgMetadata.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueMsgMetadata.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueProducer.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueProducer.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueRequestTemplate.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueRequestTemplate.java
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueResponseTemplate.java
renamed from
common/queue/src/main/java/org/thingsboard/server/queue/TbQueueResponseTemplate.java
common/cluster-api/src/main/proto/jsinvoke.proto
renamed from
common/queue/src/main/proto/jsinvoke.proto
common/cluster-api/src/main/proto/queue.proto
renamed from
common/queue/src/main/proto/queue.proto
@@ -54,6 +54,8 @@ public interface DeviceService { | @@ -54,6 +54,8 @@ public interface DeviceService { | ||
54 | 54 | ||
55 | Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials); | 55 | Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials); |
56 | 56 | ||
57 | + Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile); | ||
58 | + | ||
57 | void createAccessTokenCredentials(Device device, String accessToken); | 59 | void createAccessTokenCredentials(Device device, String accessToken); |
58 | 60 | ||
59 | Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId); | 61 | Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId); |
@@ -100,8 +102,6 @@ public interface DeviceService { | @@ -100,8 +102,6 @@ public interface DeviceService { | ||
100 | 102 | ||
101 | Device assignDeviceToTenant(TenantId tenantId, Device device); | 103 | Device assignDeviceToTenant(TenantId tenantId, Device device); |
102 | 104 | ||
103 | - Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile); | ||
104 | - | ||
105 | PageData<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType, PageLink pageLink); | 105 | PageData<UUID> findDevicesIdsByDeviceProfileTransportType(DeviceTransportType transportType, PageLink pageLink); |
106 | 106 | ||
107 | Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId); | 107 | Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId); |