Commit 1d0755f10157dfc0f2e4b6b0c905444dcd68ba2f

Authored by Igor Kulikov
2 parents bbf78721 04e21816

Merge branch 'master' of github.com:thingsboard/thingsboard

Showing 80 changed files with 1391 additions and 939 deletions

Too many changes to show.

To preserve performance only 80 of 182 files are displayed.

1 { 1 {
2 "title": "Firmware", 2 "title": "Firmware",
  3 + "image": null,
3 "configuration": { 4 "configuration": {
4 "description": "", 5 "description": "",
5 "widgets": { 6 "widgets": {
@@ -247,7 +248,7 @@ @@ -247,7 +248,7 @@
247 "name": "Edit firmware", 248 "name": "Edit firmware",
248 "icon": "edit", 249 "icon": "edit",
249 "type": "customPretty", 250 "type": "customPretty",
250 - "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-firmware-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-firmware-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>", 251 + "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-ota-package-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-ota-package-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>",
251 "customCss": "", 252 "customCss": "",
252 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", 253 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
253 "customResources": [], 254 "customResources": [],
@@ -257,7 +258,7 @@ @@ -257,7 +258,7 @@
257 "name": "Download firware", 258 "name": "Download firware",
258 "icon": "file_download", 259 "icon": "file_download",
259 "type": "custom", 260 "type": "custom",
260 - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", 261 + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
261 "id": "12533058-42f6-e75f-620c-219c48d01ec0" 262 "id": "12533058-42f6-e75f-620c-219c48d01ec0"
262 }, 263 },
263 { 264 {
@@ -1021,7 +1022,7 @@ @@ -1021,7 +1022,7 @@
1021 "name": "Edit firmware", 1022 "name": "Edit firmware",
1022 "icon": "edit", 1023 "icon": "edit",
1023 "type": "customPretty", 1024 "type": "customPretty",
1024 - "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div mat-dialog-content fxLayout=\"column\">\n <tb-firmware-autocomplete\n [useFullEntityId]=\"true\"\n formControlName=\"firmwareId\">\n </tb-firmware-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>", 1025 + "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-ota-package-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-ota-package-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>",
1025 "customCss": "", 1026 "customCss": "",
1026 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", 1027 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
1027 "customResources": [], 1028 "customResources": [],
@@ -1031,7 +1032,7 @@ @@ -1031,7 +1032,7 @@
1031 "name": "Download firware", 1032 "name": "Download firware",
1032 "icon": "file_download", 1033 "icon": "file_download",
1033 "type": "custom", 1034 "type": "custom",
1034 - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", 1035 + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
1035 "id": "12533058-42f6-e75f-620c-219c48d01ec0" 1036 "id": "12533058-42f6-e75f-620c-219c48d01ec0"
1036 }, 1037 },
1037 { 1038 {
@@ -1297,7 +1298,7 @@ @@ -1297,7 +1298,7 @@
1297 "name": "Edit firmware", 1298 "name": "Edit firmware",
1298 "icon": "edit", 1299 "icon": "edit",
1299 "type": "customPretty", 1300 "type": "customPretty",
1300 - "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div mat-dialog-content fxLayout=\"column\">\n <tb-firmware-autocomplete\n [useFullEntityId]=\"true\"\n formControlName=\"firmwareId\">\n </tb-firmware-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>", 1301 + "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-ota-package-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-ota-package-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>",
1301 "customCss": "", 1302 "customCss": "",
1302 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", 1303 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
1303 "customResources": [], 1304 "customResources": [],
@@ -1307,7 +1308,7 @@ @@ -1307,7 +1308,7 @@
1307 "name": "Download firware", 1308 "name": "Download firware",
1308 "icon": "file_download", 1309 "icon": "file_download",
1309 "type": "custom", 1310 "type": "custom",
1310 - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", 1311 + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
1311 "id": "12533058-42f6-e75f-620c-219c48d01ec0" 1312 "id": "12533058-42f6-e75f-620c-219c48d01ec0"
1312 }, 1313 },
1313 { 1314 {
@@ -1573,7 +1574,7 @@ @@ -1573,7 +1574,7 @@
1573 "name": "Edit firmware", 1574 "name": "Edit firmware",
1574 "icon": "edit", 1575 "icon": "edit",
1575 "type": "customPretty", 1576 "type": "customPretty",
1576 - "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div mat-dialog-content fxLayout=\"column\">\n <tb-firmware-autocomplete\n [useFullEntityId]=\"true\"\n formControlName=\"firmwareId\">\n </tb-firmware-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>", 1577 + "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-ota-package-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-ota-package-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>",
1577 "customCss": "", 1578 "customCss": "",
1578 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", 1579 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
1579 "customResources": [], 1580 "customResources": [],
@@ -1583,7 +1584,7 @@ @@ -1583,7 +1584,7 @@
1583 "name": "Download firware", 1584 "name": "Download firware",
1584 "icon": "file_download", 1585 "icon": "file_download",
1585 "type": "custom", 1586 "type": "custom",
1586 - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", 1587 + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
1587 "id": "12533058-42f6-e75f-620c-219c48d01ec0" 1588 "id": "12533058-42f6-e75f-620c-219c48d01ec0"
1588 }, 1589 },
1589 { 1590 {
@@ -1849,7 +1850,7 @@ @@ -1849,7 +1850,7 @@
1849 "name": "Edit firmware", 1850 "name": "Edit firmware",
1850 "icon": "edit", 1851 "icon": "edit",
1851 "type": "customPretty", 1852 "type": "customPretty",
1852 - "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div mat-dialog-content fxLayout=\"column\">\n <tb-firmware-autocomplete\n [useFullEntityId]=\"true\"\n formControlName=\"firmwareId\">\n </tb-firmware-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>", 1853 + "customHtml": "<form #editEntityForm=\"ngForm\" [formGroup]=\"editEntityFormGroup\"\n (ngSubmit)=\"save()\" class=\"edit-entity-form\">\n <mat-toolbar fxLayout=\"row\" color=\"primary\">\n <h2>Edit firmware {{entityName}}</h2>\n <span fxFlex></span>\n <button mat-icon-button (click)=\"cancel()\" type=\"button\">\n <mat-icon class=\"material-icons\">close</mat-icon>\n </button>\n </mat-toolbar>\n <mat-progress-bar color=\"warn\" mode=\"indeterminate\" *ngIf=\"isLoading$ | async\">\n </mat-progress-bar>\n <div style=\"height: 4px;\" *ngIf=\"!(isLoading$ | async)\"></div>\n <div *ngIf=\"entity.deviceProfileId\" mat-dialog-content fxLayout=\"column\">\n <tb-ota-package-autocomplete\n [useFullEntityId]=\"true\"\n [deviceProfileId]=\"entity.deviceProfileId.id\"\n formControlName=\"firmwareId\">\n </tb-ota-package-autocomplete>\n </div>\n <div mat-dialog-actions fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\"\n type=\"button\"\n [disabled]=\"(isLoading$ | async)\"\n (click)=\"cancel()\" cdkFocusInitial>\n Cancel\n </button>\n <button mat-button mat-raised-button color=\"primary\"\n type=\"submit\"\n [disabled]=\"(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty\">\n Save\n </button>\n </div>\n</form>",
1853 "customCss": "", 1854 "customCss": "",
1854 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}", 1855 "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
1855 "customResources": [], 1856 "customResources": [],
@@ -1859,7 +1860,7 @@ @@ -1859,7 +1860,7 @@
1859 "name": "Download firware", 1860 "name": "Download firware",
1860 "icon": "file_download", 1861 "icon": "file_download",
1861 "type": "custom", 1862 "type": "custom",
1862 - "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet firmwareService = $injector.get(widgetContext.servicesMap.get('firmwareService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n firmwareService.downloadFirmware(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n firmwareService.downloadFirmware(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}", 1863 + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
1863 "id": "12533058-42f6-e75f-620c-219c48d01ec0" 1864 "id": "12533058-42f6-e75f-620c-219c48d01ec0"
1864 }, 1865 },
1865 { 1866 {
@@ -59,8 +59,8 @@ CREATE TABLE IF NOT EXISTS resource ( @@ -59,8 +59,8 @@ CREATE TABLE IF NOT EXISTS resource (
59 CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key) 59 CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
60 ); 60 );
61 61
62 -CREATE TABLE IF NOT EXISTS firmware (  
63 - id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY, 62 +CREATE TABLE IF NOT EXISTS ota_package (
  63 + id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY,
64 created_time bigint NOT NULL, 64 created_time bigint NOT NULL,
65 tenant_id uuid NOT NULL, 65 tenant_id uuid NOT NULL,
66 device_profile_id uuid, 66 device_profile_id uuid,
@@ -75,7 +75,7 @@ CREATE TABLE IF NOT EXISTS firmware ( @@ -75,7 +75,7 @@ CREATE TABLE IF NOT EXISTS firmware (
75 data_size bigint, 75 data_size bigint,
76 additional_info varchar, 76 additional_info varchar,
77 search_text varchar(255), 77 search_text varchar(255),
78 - CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) 78 + CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)
79 ); 79 );
80 80
81 ALTER TABLE dashboard 81 ALTER TABLE dashboard
@@ -101,13 +101,13 @@ DO $$ @@ -101,13 +101,13 @@ DO $$
101 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN 101 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN
102 ALTER TABLE device_profile 102 ALTER TABLE device_profile
103 ADD CONSTRAINT fk_firmware_device_profile 103 ADD CONSTRAINT fk_firmware_device_profile
104 - FOREIGN KEY (firmware_id) REFERENCES firmware(id); 104 + FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
105 END IF; 105 END IF;
106 106
107 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN 107 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN
108 ALTER TABLE device_profile 108 ALTER TABLE device_profile
109 ADD CONSTRAINT fk_software_device_profile 109 ADD CONSTRAINT fk_software_device_profile
110 - FOREIGN KEY (firmware_id) REFERENCES firmware(id); 110 + FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
111 END IF; 111 END IF;
112 112
113 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN 113 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN
@@ -119,13 +119,13 @@ DO $$ @@ -119,13 +119,13 @@ DO $$
119 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN 119 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN
120 ALTER TABLE device 120 ALTER TABLE device
121 ADD CONSTRAINT fk_firmware_device 121 ADD CONSTRAINT fk_firmware_device
122 - FOREIGN KEY (firmware_id) REFERENCES firmware(id); 122 + FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
123 END IF; 123 END IF;
124 124
125 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN 125 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN
126 ALTER TABLE device 126 ALTER TABLE device
127 ADD CONSTRAINT fk_software_device 127 ADD CONSTRAINT fk_software_device
128 - FOREIGN KEY (firmware_id) REFERENCES firmware(id); 128 + FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
129 END IF; 129 END IF;
130 END; 130 END;
131 $$; 131 $$;
@@ -317,25 +317,48 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -317,25 +317,48 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
317 317
318 private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { 318 private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) {
319 int requestId = request.getRequestId(); 319 int requestId = request.getRequestId();
320 - Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<List<List<AttributeKvEntry>>>() {  
321 - @Override  
322 - public void onSuccess(@Nullable List<List<AttributeKvEntry>> result) {  
323 - GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()  
324 - .setRequestId(requestId)  
325 - .addAllClientAttributeList(toTsKvProtos(result.get(0)))  
326 - .addAllSharedAttributeList(toTsKvProtos(result.get(1)))  
327 - .build();  
328 - sendToTransport(responseMsg, sessionInfo);  
329 - } 320 + if (request.getOnlyShared()) {
  321 + Futures.addCallback(findAllAttributesByScope(DataConstants.SHARED_SCOPE), new FutureCallback<>() {
  322 + @Override
  323 + public void onSuccess(@Nullable List<AttributeKvEntry> result) {
  324 + GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
  325 + .setRequestId(requestId)
  326 + .setSharedStateMsg(true)
  327 + .addAllSharedAttributeList(toTsKvProtos(result))
  328 + .build();
  329 + sendToTransport(responseMsg, sessionInfo);
  330 + }
330 331
331 - @Override  
332 - public void onFailure(Throwable t) {  
333 - GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()  
334 - .setError(t.getMessage())  
335 - .build();  
336 - sendToTransport(responseMsg, sessionInfo);  
337 - }  
338 - }, MoreExecutors.directExecutor()); 332 + @Override
  333 + public void onFailure(Throwable t) {
  334 + GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
  335 + .setError(t.getMessage())
  336 + .setSharedStateMsg(true)
  337 + .build();
  338 + sendToTransport(responseMsg, sessionInfo);
  339 + }
  340 + }, MoreExecutors.directExecutor());
  341 + } else {
  342 + Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<>() {
  343 + @Override
  344 + public void onSuccess(@Nullable List<List<AttributeKvEntry>> result) {
  345 + GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
  346 + .setRequestId(requestId)
  347 + .addAllClientAttributeList(toTsKvProtos(result.get(0)))
  348 + .addAllSharedAttributeList(toTsKvProtos(result.get(1)))
  349 + .build();
  350 + sendToTransport(responseMsg, sessionInfo);
  351 + }
  352 +
  353 + @Override
  354 + public void onFailure(Throwable t) {
  355 + GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
  356 + .setError(t.getMessage())
  357 + .build();
  358 + sendToTransport(responseMsg, sessionInfo);
  359 + }
  360 + }, MoreExecutors.directExecutor());
  361 + }
339 } 362 }
340 363
341 private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) { 364 private ListenableFuture<List<List<AttributeKvEntry>>> getAttributesKvEntries(GetAttributeRequestMsg request) {
@@ -403,9 +426,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -403,9 +426,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
403 } 426 }
404 if (hasNotificationData) { 427 if (hasNotificationData) {
405 AttributeUpdateNotificationMsg finalNotification = notification.build(); 428 AttributeUpdateNotificationMsg finalNotification = notification.build();
406 - attributeSubscriptions.entrySet().forEach(sub -> {  
407 - sendToTransport(finalNotification, sub.getKey(), sub.getValue().getNodeId());  
408 - }); 429 + attributeSubscriptions.forEach((key, value) -> sendToTransport(finalNotification, key, value.getNodeId()));
409 } 430 }
410 } else { 431 } else {
411 log.debug("[{}] No registered attributes subscriptions to process!", deviceId); 432 log.debug("[{}] No registered attributes subscriptions to process!", deviceId);
@@ -475,7 +496,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -475,7 +496,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
475 if (sessions.size() >= systemContext.getMaxConcurrentSessionsPerDevice()) { 496 if (sessions.size() >= systemContext.getMaxConcurrentSessionsPerDevice()) {
476 UUID sessionIdToRemove = sessions.keySet().stream().findFirst().orElse(null); 497 UUID sessionIdToRemove = sessions.keySet().stream().findFirst().orElse(null);
477 if (sessionIdToRemove != null) { 498 if (sessionIdToRemove != null) {
478 - notifyTransportAboutClosedSession(sessionIdToRemove, sessions.remove(sessionIdToRemove)); 499 + notifyTransportAboutClosedSession(sessionIdToRemove, sessions.remove(sessionIdToRemove), "max concurrent sessions limit reached per device!");
479 } 500 }
480 } 501 }
481 sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId()))); 502 sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId())));
@@ -521,7 +542,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -521,7 +542,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
521 notifyTransportAboutProfileUpdate(k, v, ((DeviceCredentialsUpdateNotificationMsg) msg).getDeviceCredentials()); 542 notifyTransportAboutProfileUpdate(k, v, ((DeviceCredentialsUpdateNotificationMsg) msg).getDeviceCredentials());
522 }); 543 });
523 } else { 544 } else {
524 - sessions.forEach(this::notifyTransportAboutClosedSession); 545 + sessions.forEach((sessionId, sessionMd) -> notifyTransportAboutClosedSession(sessionId, sessionMd, "device credentials updated!"));
525 attributeSubscriptions.clear(); 546 attributeSubscriptions.clear();
526 rpcSubscriptions.clear(); 547 rpcSubscriptions.clear();
527 dumpSessions(); 548 dumpSessions();
@@ -529,11 +550,15 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -529,11 +550,15 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
529 } 550 }
530 } 551 }
531 552
532 - private void notifyTransportAboutClosedSession(UUID sessionId, SessionInfoMetaData sessionMd) { 553 + private void notifyTransportAboutClosedSession(UUID sessionId, SessionInfoMetaData sessionMd, String message) {
  554 + SessionCloseNotificationProto sessionCloseNotificationProto = SessionCloseNotificationProto
  555 + .newBuilder()
  556 + .setMessage(message).build();
533 ToTransportMsg msg = ToTransportMsg.newBuilder() 557 ToTransportMsg msg = ToTransportMsg.newBuilder()
534 .setSessionIdMSB(sessionId.getMostSignificantBits()) 558 .setSessionIdMSB(sessionId.getMostSignificantBits())
535 .setSessionIdLSB(sessionId.getLeastSignificantBits()) 559 .setSessionIdLSB(sessionId.getLeastSignificantBits())
536 - .setSessionCloseNotification(SessionCloseNotificationProto.getDefaultInstance()).build(); 560 + .setSessionCloseNotification(sessionCloseNotificationProto)
  561 + .build();
537 systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg); 562 systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
538 } 563 }
539 564
@@ -741,7 +766,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -741,7 +766,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
741 sessions.remove(sessionId); 766 sessions.remove(sessionId);
742 rpcSubscriptions.remove(sessionId); 767 rpcSubscriptions.remove(sessionId);
743 attributeSubscriptions.remove(sessionId); 768 attributeSubscriptions.remove(sessionId);
744 - notifyTransportAboutClosedSession(sessionId, sessionMD); 769 + notifyTransportAboutClosedSession(sessionId, sessionMD, "session timeout!");
745 }); 770 });
746 if (!sessionsToRemove.isEmpty()) { 771 if (!sessionsToRemove.isEmpty()) {
747 dumpSessions(); 772 dumpSessions();
@@ -110,8 +110,11 @@ public class AlarmController extends BaseController { @@ -110,8 +110,11 @@ public class AlarmController extends BaseController {
110 checkParameter(ALARM_ID, strAlarmId); 110 checkParameter(ALARM_ID, strAlarmId);
111 try { 111 try {
112 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 112 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
113 - checkAlarmId(alarmId, Operation.WRITE); 113 + Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
114 114
  115 + logEntityAction(alarm.getOriginator(), alarm,
  116 + getCurrentUser().getCustomerId(),
  117 + ActionType.ALARM_DELETE, null);
115 sendEntityNotificationMsg(getTenantId(), alarmId, EdgeEventActionType.DELETED); 118 sendEntityNotificationMsg(getTenantId(), alarmId, EdgeEventActionType.DELETED);
116 119
117 return alarmService.deleteAlarm(getTenantId(), alarmId); 120 return alarmService.deleteAlarm(getTenantId(), alarmId);
@@ -17,7 +17,6 @@ package org.thingsboard.server.controller; @@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
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.databind.node.ArrayNode;  
21 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
22 import lombok.Getter; 21 import lombok.Getter;
23 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
@@ -31,7 +30,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler; @@ -31,7 +30,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
31 import org.thingsboard.server.common.data.Customer; 30 import org.thingsboard.server.common.data.Customer;
32 import org.thingsboard.server.common.data.Dashboard; 31 import org.thingsboard.server.common.data.Dashboard;
33 import org.thingsboard.server.common.data.DashboardInfo; 32 import org.thingsboard.server.common.data.DashboardInfo;
34 -import org.thingsboard.server.common.data.DataConstants;  
35 import org.thingsboard.server.common.data.Device; 33 import org.thingsboard.server.common.data.Device;
36 import org.thingsboard.server.common.data.DeviceInfo; 34 import org.thingsboard.server.common.data.DeviceInfo;
37 import org.thingsboard.server.common.data.DeviceProfile; 35 import org.thingsboard.server.common.data.DeviceProfile;
@@ -39,8 +37,8 @@ import org.thingsboard.server.common.data.EdgeUtils; @@ -39,8 +37,8 @@ import org.thingsboard.server.common.data.EdgeUtils;
39 import org.thingsboard.server.common.data.EntityType; 37 import org.thingsboard.server.common.data.EntityType;
40 import org.thingsboard.server.common.data.EntityView; 38 import org.thingsboard.server.common.data.EntityView;
41 import org.thingsboard.server.common.data.EntityViewInfo; 39 import org.thingsboard.server.common.data.EntityViewInfo;
42 -import org.thingsboard.server.common.data.Firmware;  
43 -import org.thingsboard.server.common.data.FirmwareInfo; 40 +import org.thingsboard.server.common.data.OtaPackage;
  41 +import org.thingsboard.server.common.data.OtaPackageInfo;
44 import org.thingsboard.server.common.data.HasName; 42 import org.thingsboard.server.common.data.HasName;
45 import org.thingsboard.server.common.data.HasTenantId; 43 import org.thingsboard.server.common.data.HasTenantId;
46 import org.thingsboard.server.common.data.TbResourceInfo; 44 import org.thingsboard.server.common.data.TbResourceInfo;
@@ -70,7 +68,7 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -70,7 +68,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
70 import org.thingsboard.server.common.data.id.EntityId; 68 import org.thingsboard.server.common.data.id.EntityId;
71 import org.thingsboard.server.common.data.id.EntityIdFactory; 69 import org.thingsboard.server.common.data.id.EntityIdFactory;
72 import org.thingsboard.server.common.data.id.EntityViewId; 70 import org.thingsboard.server.common.data.id.EntityViewId;
73 -import org.thingsboard.server.common.data.id.FirmwareId; 71 +import org.thingsboard.server.common.data.id.OtaPackageId;
74 import org.thingsboard.server.common.data.id.TbResourceId; 72 import org.thingsboard.server.common.data.id.TbResourceId;
75 import org.thingsboard.server.common.data.id.RuleChainId; 73 import org.thingsboard.server.common.data.id.RuleChainId;
76 import org.thingsboard.server.common.data.id.RuleNodeId; 74 import org.thingsboard.server.common.data.id.RuleNodeId;
@@ -79,10 +77,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId; @@ -79,10 +77,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId;
79 import org.thingsboard.server.common.data.id.UserId; 77 import org.thingsboard.server.common.data.id.UserId;
80 import org.thingsboard.server.common.data.id.WidgetTypeId; 78 import org.thingsboard.server.common.data.id.WidgetTypeId;
81 import org.thingsboard.server.common.data.id.WidgetsBundleId; 79 import org.thingsboard.server.common.data.id.WidgetsBundleId;
82 -import org.thingsboard.server.common.data.kv.AttributeKvEntry;  
83 -import org.thingsboard.server.common.data.kv.DataType;  
84 -import org.thingsboard.server.common.data.kv.KvEntry;  
85 -import org.thingsboard.server.common.data.kv.TsKvEntry;  
86 import org.thingsboard.server.common.data.page.PageLink; 80 import org.thingsboard.server.common.data.page.PageLink;
87 import org.thingsboard.server.common.data.page.SortOrder; 81 import org.thingsboard.server.common.data.page.SortOrder;
88 import org.thingsboard.server.common.data.page.TimePageLink; 82 import org.thingsboard.server.common.data.page.TimePageLink;
@@ -94,9 +88,6 @@ import org.thingsboard.server.common.data.rule.RuleChainType; @@ -94,9 +88,6 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
94 import org.thingsboard.server.common.data.rule.RuleNode; 88 import org.thingsboard.server.common.data.rule.RuleNode;
95 import org.thingsboard.server.common.data.widget.WidgetTypeDetails; 89 import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
96 import org.thingsboard.server.common.data.widget.WidgetsBundle; 90 import org.thingsboard.server.common.data.widget.WidgetsBundle;
97 -import org.thingsboard.server.common.msg.TbMsg;  
98 -import org.thingsboard.server.common.msg.TbMsgDataType;  
99 -import org.thingsboard.server.common.msg.TbMsgMetaData;  
100 import org.thingsboard.server.dao.asset.AssetService; 91 import org.thingsboard.server.dao.asset.AssetService;
101 import org.thingsboard.server.dao.attributes.AttributesService; 92 import org.thingsboard.server.dao.attributes.AttributesService;
102 import org.thingsboard.server.dao.audit.AuditLogService; 93 import org.thingsboard.server.dao.audit.AuditLogService;
@@ -110,7 +101,7 @@ import org.thingsboard.server.dao.edge.EdgeService; @@ -110,7 +101,7 @@ import org.thingsboard.server.dao.edge.EdgeService;
110 import org.thingsboard.server.dao.entityview.EntityViewService; 101 import org.thingsboard.server.dao.entityview.EntityViewService;
111 import org.thingsboard.server.dao.exception.DataValidationException; 102 import org.thingsboard.server.dao.exception.DataValidationException;
112 import org.thingsboard.server.dao.exception.IncorrectParameterException; 103 import org.thingsboard.server.dao.exception.IncorrectParameterException;
113 -import org.thingsboard.server.dao.firmware.FirmwareService; 104 +import org.thingsboard.server.dao.ota.OtaPackageService;
114 import org.thingsboard.server.dao.model.ModelConstants; 105 import org.thingsboard.server.dao.model.ModelConstants;
115 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; 106 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
116 import org.thingsboard.server.dao.oauth2.OAuth2Service; 107 import org.thingsboard.server.dao.oauth2.OAuth2Service;
@@ -127,8 +118,9 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -127,8 +118,9 @@ import org.thingsboard.server.gen.transport.TransportProtos;
127 import org.thingsboard.server.queue.discovery.PartitionService; 118 import org.thingsboard.server.queue.discovery.PartitionService;
128 import org.thingsboard.server.queue.provider.TbQueueProducerProvider; 119 import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
129 import org.thingsboard.server.queue.util.TbCoreComponent; 120 import org.thingsboard.server.queue.util.TbCoreComponent;
  121 +import org.thingsboard.server.service.action.RuleEngineEntityActionService;
130 import org.thingsboard.server.service.component.ComponentDiscoveryService; 122 import org.thingsboard.server.service.component.ComponentDiscoveryService;
131 -import org.thingsboard.server.service.firmware.FirmwareStateService; 123 +import org.thingsboard.server.service.ota.OtaPackageStateService;
132 import org.thingsboard.server.service.edge.EdgeNotificationService; 124 import org.thingsboard.server.service.edge.EdgeNotificationService;
133 import org.thingsboard.server.service.edge.rpc.EdgeGrpcService; 125 import org.thingsboard.server.service.edge.rpc.EdgeGrpcService;
134 import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService; 126 import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService;
@@ -147,11 +139,9 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; @@ -147,11 +139,9 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
147 import javax.mail.MessagingException; 139 import javax.mail.MessagingException;
148 import javax.servlet.http.HttpServletResponse; 140 import javax.servlet.http.HttpServletResponse;
149 import java.util.List; 141 import java.util.List;
150 -import java.util.Map;  
151 import java.util.Optional; 142 import java.util.Optional;
152 import java.util.Set; 143 import java.util.Set;
153 import java.util.UUID; 144 import java.util.UUID;
154 -import java.util.stream.Collectors;  
155 145
156 import static org.thingsboard.server.dao.service.Validator.validateId; 146 import static org.thingsboard.server.dao.service.Validator.validateId;
157 147
@@ -250,10 +240,10 @@ public abstract class BaseController { @@ -250,10 +240,10 @@ public abstract class BaseController {
250 protected TbResourceService resourceService; 240 protected TbResourceService resourceService;
251 241
252 @Autowired 242 @Autowired
253 - protected FirmwareService firmwareService; 243 + protected OtaPackageService otaPackageService;
254 244
255 @Autowired 245 @Autowired
256 - protected FirmwareStateService firmwareStateService; 246 + protected OtaPackageStateService otaPackageStateService;
257 247
258 @Autowired 248 @Autowired
259 protected TbQueueProducerProvider producerProvider; 249 protected TbQueueProducerProvider producerProvider;
@@ -279,6 +269,9 @@ public abstract class BaseController { @@ -279,6 +269,9 @@ public abstract class BaseController {
279 @Autowired(required = false) 269 @Autowired(required = false)
280 protected EdgeGrpcService edgeGrpcService; 270 protected EdgeGrpcService edgeGrpcService;
281 271
  272 + @Autowired
  273 + protected RuleEngineEntityActionService ruleEngineEntityActionService;
  274 +
282 @Value("${server.log_controller_error_stack_trace}") 275 @Value("${server.log_controller_error_stack_trace}")
283 @Getter 276 @Getter
284 private boolean logControllerErrorStackTrace; 277 private boolean logControllerErrorStackTrace;
@@ -511,8 +504,8 @@ public abstract class BaseController { @@ -511,8 +504,8 @@ public abstract class BaseController {
511 case TB_RESOURCE: 504 case TB_RESOURCE:
512 checkResourceId(new TbResourceId(entityId.getId()), operation); 505 checkResourceId(new TbResourceId(entityId.getId()), operation);
513 return; 506 return;
514 - case FIRMWARE:  
515 - checkFirmwareId(new FirmwareId(entityId.getId()), operation); 507 + case OTA_PACKAGE:
  508 + checkOtaPackageId(new OtaPackageId(entityId.getId()), operation);
516 return; 509 return;
517 default: 510 default:
518 throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); 511 throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType());
@@ -769,25 +762,25 @@ public abstract class BaseController { @@ -769,25 +762,25 @@ public abstract class BaseController {
769 } 762 }
770 } 763 }
771 764
772 - Firmware checkFirmwareId(FirmwareId firmwareId, Operation operation) throws ThingsboardException { 765 + OtaPackage checkOtaPackageId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException {
773 try { 766 try {
774 - validateId(firmwareId, "Incorrect firmwareId " + firmwareId);  
775 - Firmware firmware = firmwareService.findFirmwareById(getCurrentUser().getTenantId(), firmwareId);  
776 - checkNotNull(firmware);  
777 - accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmware);  
778 - return firmware; 767 + validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
  768 + OtaPackage otaPackage = otaPackageService.findOtaPackageById(getCurrentUser().getTenantId(), otaPackageId);
  769 + checkNotNull(otaPackage);
  770 + accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackage);
  771 + return otaPackage;
779 } catch (Exception e) { 772 } catch (Exception e) {
780 throw handleException(e, false); 773 throw handleException(e, false);
781 } 774 }
782 } 775 }
783 776
784 - FirmwareInfo checkFirmwareInfoId(FirmwareId firmwareId, Operation operation) throws ThingsboardException { 777 + OtaPackageInfo checkOtaPackageInfoId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException {
785 try { 778 try {
786 - validateId(firmwareId, "Incorrect firmwareId " + firmwareId);  
787 - FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(getCurrentUser().getTenantId(), firmwareId);  
788 - checkNotNull(firmwareInfo);  
789 - accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmwareInfo);  
790 - return firmwareInfo; 779 + validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
  780 + OtaPackageInfo otaPackageIn = otaPackageService.findOtaPackageInfoById(getCurrentUser().getTenantId(), otaPackageId);
  781 + checkNotNull(otaPackageIn);
  782 + accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackageIn);
  783 + return otaPackageIn;
791 } catch (Exception e) { 784 } catch (Exception e) {
792 throw handleException(e, false); 785 throw handleException(e, false);
793 } 786 }
@@ -809,7 +802,7 @@ public abstract class BaseController { @@ -809,7 +802,7 @@ public abstract class BaseController {
809 customerId = user.getCustomerId(); 802 customerId = user.getCustomerId();
810 } 803 }
811 if (e == null) { 804 if (e == null) {
812 - pushEntityActionToRuleEngine(entityId, entity, user, customerId, actionType, additionalInfo); 805 + ruleEngineEntityActionService.pushEntityActionToRuleEngine(entityId, entity, user.getTenantId(), customerId, actionType, user, additionalInfo);
813 } 806 }
814 auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo); 807 auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo);
815 } 808 }
@@ -819,184 +812,6 @@ public abstract class BaseController { @@ -819,184 +812,6 @@ public abstract class BaseController {
819 return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null; 812 return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null;
820 } 813 }
821 814
822 - private <E extends HasName, I extends EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,  
823 - ActionType actionType, Object... additionalInfo) {  
824 - String msgType = null;  
825 - switch (actionType) {  
826 - case ADDED:  
827 - msgType = DataConstants.ENTITY_CREATED;  
828 - break;  
829 - case DELETED:  
830 - msgType = DataConstants.ENTITY_DELETED;  
831 - break;  
832 - case UPDATED:  
833 - msgType = DataConstants.ENTITY_UPDATED;  
834 - break;  
835 - case ASSIGNED_TO_CUSTOMER:  
836 - msgType = DataConstants.ENTITY_ASSIGNED;  
837 - break;  
838 - case UNASSIGNED_FROM_CUSTOMER:  
839 - msgType = DataConstants.ENTITY_UNASSIGNED;  
840 - break;  
841 - case ATTRIBUTES_UPDATED:  
842 - msgType = DataConstants.ATTRIBUTES_UPDATED;  
843 - break;  
844 - case ATTRIBUTES_DELETED:  
845 - msgType = DataConstants.ATTRIBUTES_DELETED;  
846 - break;  
847 - case ALARM_ACK:  
848 - msgType = DataConstants.ALARM_ACK;  
849 - break;  
850 - case ALARM_CLEAR:  
851 - msgType = DataConstants.ALARM_CLEAR;  
852 - break;  
853 - case ASSIGNED_FROM_TENANT:  
854 - msgType = DataConstants.ENTITY_ASSIGNED_FROM_TENANT;  
855 - break;  
856 - case ASSIGNED_TO_TENANT:  
857 - msgType = DataConstants.ENTITY_ASSIGNED_TO_TENANT;  
858 - break;  
859 - case PROVISION_SUCCESS:  
860 - msgType = DataConstants.PROVISION_SUCCESS;  
861 - break;  
862 - case PROVISION_FAILURE:  
863 - msgType = DataConstants.PROVISION_FAILURE;  
864 - break;  
865 - case TIMESERIES_UPDATED:  
866 - msgType = DataConstants.TIMESERIES_UPDATED;  
867 - break;  
868 - case TIMESERIES_DELETED:  
869 - msgType = DataConstants.TIMESERIES_DELETED;  
870 - break;  
871 - case ASSIGNED_TO_EDGE:  
872 - msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;  
873 - break;  
874 - case UNASSIGNED_FROM_EDGE:  
875 - msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;  
876 - break;  
877 - }  
878 - if (!StringUtils.isEmpty(msgType)) {  
879 - try {  
880 - TbMsgMetaData metaData = new TbMsgMetaData();  
881 - metaData.putValue("userId", user.getId().toString());  
882 - metaData.putValue("userName", user.getName());  
883 - if (customerId != null && !customerId.isNullUid()) {  
884 - metaData.putValue("customerId", customerId.toString());  
885 - }  
886 - if (actionType == ActionType.ASSIGNED_TO_CUSTOMER) {  
887 - String strCustomerId = extractParameter(String.class, 1, additionalInfo);  
888 - String strCustomerName = extractParameter(String.class, 2, additionalInfo);  
889 - metaData.putValue("assignedCustomerId", strCustomerId);  
890 - metaData.putValue("assignedCustomerName", strCustomerName);  
891 - } else if (actionType == ActionType.UNASSIGNED_FROM_CUSTOMER) {  
892 - String strCustomerId = extractParameter(String.class, 1, additionalInfo);  
893 - String strCustomerName = extractParameter(String.class, 2, additionalInfo);  
894 - metaData.putValue("unassignedCustomerId", strCustomerId);  
895 - metaData.putValue("unassignedCustomerName", strCustomerName);  
896 - } else if (actionType == ActionType.ASSIGNED_FROM_TENANT) {  
897 - String strTenantId = extractParameter(String.class, 0, additionalInfo);  
898 - String strTenantName = extractParameter(String.class, 1, additionalInfo);  
899 - metaData.putValue("assignedFromTenantId", strTenantId);  
900 - metaData.putValue("assignedFromTenantName", strTenantName);  
901 - } else if (actionType == ActionType.ASSIGNED_TO_TENANT) {  
902 - String strTenantId = extractParameter(String.class, 0, additionalInfo);  
903 - String strTenantName = extractParameter(String.class, 1, additionalInfo);  
904 - metaData.putValue("assignedToTenantId", strTenantId);  
905 - metaData.putValue("assignedToTenantName", strTenantName);  
906 - } else if (actionType == ActionType.ASSIGNED_TO_EDGE) {  
907 - String strEdgeId = extractParameter(String.class, 1, additionalInfo);  
908 - String strEdgeName = extractParameter(String.class, 2, additionalInfo);  
909 - metaData.putValue("assignedEdgeId", strEdgeId);  
910 - metaData.putValue("assignedEdgeName", strEdgeName);  
911 - } else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {  
912 - String strEdgeId = extractParameter(String.class, 1, additionalInfo);  
913 - String strEdgeName = extractParameter(String.class, 2, additionalInfo);  
914 - metaData.putValue("unassignedEdgeId", strEdgeId);  
915 - metaData.putValue("unassignedEdgeName", strEdgeName);  
916 - }  
917 - ObjectNode entityNode;  
918 - if (entity != null) {  
919 - entityNode = json.valueToTree(entity);  
920 - if (entityId.getEntityType() == EntityType.DASHBOARD) {  
921 - entityNode.put("configuration", "");  
922 - }  
923 - } else {  
924 - entityNode = json.createObjectNode();  
925 - if (actionType == ActionType.ATTRIBUTES_UPDATED) {  
926 - String scope = extractParameter(String.class, 0, additionalInfo);  
927 - @SuppressWarnings("unchecked")  
928 - List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo);  
929 - metaData.putValue(DataConstants.SCOPE, scope);  
930 - if (attributes != null) {  
931 - for (AttributeKvEntry attr : attributes) {  
932 - addKvEntry(entityNode, attr);  
933 - }  
934 - }  
935 - } else if (actionType == ActionType.ATTRIBUTES_DELETED) {  
936 - String scope = extractParameter(String.class, 0, additionalInfo);  
937 - @SuppressWarnings("unchecked")  
938 - List<String> keys = extractParameter(List.class, 1, additionalInfo);  
939 - metaData.putValue(DataConstants.SCOPE, scope);  
940 - ArrayNode attrsArrayNode = entityNode.putArray("attributes");  
941 - if (keys != null) {  
942 - keys.forEach(attrsArrayNode::add);  
943 - }  
944 - } else if (actionType == ActionType.TIMESERIES_UPDATED) {  
945 - @SuppressWarnings("unchecked")  
946 - List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);  
947 - addTimeseries(entityNode, timeseries);  
948 - } else if (actionType == ActionType.TIMESERIES_DELETED) {  
949 - @SuppressWarnings("unchecked")  
950 - List<String> keys = extractParameter(List.class, 0, additionalInfo);  
951 - if (keys != null) {  
952 - ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");  
953 - keys.forEach(timeseriesArrayNode::add);  
954 - }  
955 - entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));  
956 - entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));  
957 - }  
958 - }  
959 - TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));  
960 - TenantId tenantId = user.getTenantId();  
961 - if (tenantId.isNullUid()) {  
962 - if (entity instanceof HasTenantId) {  
963 - tenantId = ((HasTenantId) entity).getTenantId();  
964 - }  
965 - }  
966 - tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null);  
967 - } catch (Exception e) {  
968 - log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);  
969 - }  
970 - }  
971 - }  
972 -  
973 - private void addKvEntry(ObjectNode entityNode, KvEntry kvEntry) throws Exception {  
974 - if (kvEntry.getDataType() == DataType.BOOLEAN) {  
975 - kvEntry.getBooleanValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));  
976 - } else if (kvEntry.getDataType() == DataType.DOUBLE) {  
977 - kvEntry.getDoubleValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));  
978 - } else if (kvEntry.getDataType() == DataType.LONG) {  
979 - kvEntry.getLongValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));  
980 - } else if (kvEntry.getDataType() == DataType.JSON) {  
981 - if (kvEntry.getJsonValue().isPresent()) {  
982 - entityNode.set(kvEntry.getKey(), json.readTree(kvEntry.getJsonValue().get()));  
983 - }  
984 - } else {  
985 - entityNode.put(kvEntry.getKey(), kvEntry.getValueAsString());  
986 - }  
987 - }  
988 -  
989 - private <T> T extractParameter(Class<T> clazz, int index, Object... additionalInfo) {  
990 - T result = null;  
991 - if (additionalInfo != null && additionalInfo.length > index) {  
992 - Object paramObject = additionalInfo[index];  
993 - if (clazz.isInstance(paramObject)) {  
994 - result = clazz.cast(paramObject);  
995 - }  
996 - }  
997 - return result;  
998 - }  
999 -  
1000 protected <E extends HasName> String entityToStr(E entity) { 815 protected <E extends HasName> String entityToStr(E entity) {
1001 try { 816 try {
1002 return json.writeValueAsString(json.valueToTree(entity)); 817 return json.writeValueAsString(json.valueToTree(entity));
@@ -1093,23 +908,6 @@ public abstract class BaseController { @@ -1093,23 +908,6 @@ public abstract class BaseController {
1093 return result; 908 return result;
1094 } 909 }
1095 910
1096 - private void addTimeseries(ObjectNode entityNode, List<TsKvEntry> timeseries) throws Exception {  
1097 - if (timeseries != null && !timeseries.isEmpty()) {  
1098 - ArrayNode result = entityNode.putArray("timeseries");  
1099 - Map<Long, List<TsKvEntry>> groupedTelemetry = timeseries.stream()  
1100 - .collect(Collectors.groupingBy(TsKvEntry::getTs));  
1101 - for (Map.Entry<Long, List<TsKvEntry>> entry : groupedTelemetry.entrySet()) {  
1102 - ObjectNode element = json.createObjectNode();  
1103 - element.put("ts", entry.getKey());  
1104 - ObjectNode values = element.putObject("values");  
1105 - for (TsKvEntry tsKvEntry : entry.getValue()) {  
1106 - addKvEntry(values, tsKvEntry);  
1107 - }  
1108 - result.add(element);  
1109 - }  
1110 - }  
1111 - }  
1112 -  
1113 protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException { 911 protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException {
1114 String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null; 912 String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null;
1115 if (dashboardId != null && !dashboardId.equals("null")) { 913 if (dashboardId != null && !dashboardId.equals("null")) {
@@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId; @@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
53 import org.thingsboard.server.common.data.id.DeviceProfileId; 53 import org.thingsboard.server.common.data.id.DeviceProfileId;
54 import org.thingsboard.server.common.data.id.EdgeId; 54 import org.thingsboard.server.common.data.id.EdgeId;
55 import org.thingsboard.server.common.data.id.TenantId; 55 import org.thingsboard.server.common.data.id.TenantId;
  56 +import org.thingsboard.server.common.data.ota.OtaPackageType;
56 import org.thingsboard.server.common.data.page.PageData; 57 import org.thingsboard.server.common.data.page.PageData;
57 import org.thingsboard.server.common.data.page.PageLink; 58 import org.thingsboard.server.common.data.page.PageLink;
58 import org.thingsboard.server.common.data.page.TimePageLink; 59 import org.thingsboard.server.common.data.page.TimePageLink;
@@ -75,6 +76,7 @@ import javax.annotation.Nullable; @@ -75,6 +76,7 @@ import javax.annotation.Nullable;
75 import java.io.IOException; 76 import java.io.IOException;
76 import java.util.ArrayList; 77 import java.util.ArrayList;
77 import java.util.List; 78 import java.util.List;
  79 +import java.util.UUID;
78 import java.util.stream.Collectors; 80 import java.util.stream.Collectors;
79 81
80 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 82 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
@@ -153,7 +155,7 @@ public class DeviceController extends BaseController { @@ -153,7 +155,7 @@ public class DeviceController extends BaseController {
153 deviceStateService.onDeviceUpdated(savedDevice); 155 deviceStateService.onDeviceUpdated(savedDevice);
154 } 156 }
155 157
156 - firmwareStateService.update(savedDevice, oldDevice); 158 + otaPackageStateService.update(savedDevice, oldDevice);
157 159
158 return savedDevice; 160 return savedDevice;
159 } catch (Exception e) { 161 } catch (Exception e) {
@@ -778,4 +780,19 @@ public class DeviceController extends BaseController { @@ -778,4 +780,19 @@ public class DeviceController extends BaseController {
778 throw handleException(e); 780 throw handleException(e);
779 } 781 }
780 } 782 }
  783 +
  784 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
  785 + @RequestMapping(value = "/devices/count/{otaPackageType}", method = RequestMethod.GET)
  786 + @ResponseBody
  787 + public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(@PathVariable("otaPackageType") String otaPackageType,
  788 + @RequestParam String deviceProfileId) throws ThingsboardException {
  789 + checkParameter("OtaPackageType", otaPackageType);
  790 + checkParameter("DeviceProfileId", deviceProfileId);
  791 + try {
  792 + return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(
  793 + getCurrentUser().getTenantId(), new DeviceProfileId(UUID.fromString(deviceProfileId)), OtaPackageType.valueOf(otaPackageType));
  794 + } catch (Exception e) {
  795 + throw handleException(e);
  796 + }
  797 + }
781 } 798 }
@@ -168,7 +168,7 @@ public class DeviceProfileController extends BaseController { @@ -168,7 +168,7 @@ public class DeviceProfileController extends BaseController {
168 null, 168 null,
169 created ? ActionType.ADDED : ActionType.UPDATED, null); 169 created ? ActionType.ADDED : ActionType.UPDATED, null);
170 170
171 - firmwareStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); 171 + otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
172 172
173 sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(), 173 sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(),
174 deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); 174 deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java renamed from application/src/main/java/org/thingsboard/server/controller/FirmwareController.java
@@ -30,14 +30,14 @@ import org.springframework.web.bind.annotation.ResponseBody; @@ -30,14 +30,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
30 import org.springframework.web.bind.annotation.RestController; 30 import org.springframework.web.bind.annotation.RestController;
31 import org.springframework.web.multipart.MultipartFile; 31 import org.springframework.web.multipart.MultipartFile;
32 import org.thingsboard.server.common.data.EntityType; 32 import org.thingsboard.server.common.data.EntityType;
33 -import org.thingsboard.server.common.data.Firmware;  
34 -import org.thingsboard.server.common.data.FirmwareInfo; 33 +import org.thingsboard.server.common.data.OtaPackage;
  34 +import org.thingsboard.server.common.data.OtaPackageInfo;
35 import org.thingsboard.server.common.data.audit.ActionType; 35 import org.thingsboard.server.common.data.audit.ActionType;
36 import org.thingsboard.server.common.data.exception.ThingsboardException; 36 import org.thingsboard.server.common.data.exception.ThingsboardException;
37 -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;  
38 -import org.thingsboard.server.common.data.firmware.FirmwareType; 37 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  38 +import org.thingsboard.server.common.data.ota.OtaPackageType;
39 import org.thingsboard.server.common.data.id.DeviceProfileId; 39 import org.thingsboard.server.common.data.id.DeviceProfileId;
40 -import org.thingsboard.server.common.data.id.FirmwareId; 40 +import org.thingsboard.server.common.data.id.OtaPackageId;
41 import org.thingsboard.server.common.data.page.PageData; 41 import org.thingsboard.server.common.data.page.PageData;
42 import org.thingsboard.server.common.data.page.PageLink; 42 import org.thingsboard.server.common.data.page.PageLink;
43 import org.thingsboard.server.queue.util.TbCoreComponent; 43 import org.thingsboard.server.queue.util.TbCoreComponent;
@@ -50,26 +50,26 @@ import java.nio.ByteBuffer; @@ -50,26 +50,26 @@ import java.nio.ByteBuffer;
50 @RestController 50 @RestController
51 @TbCoreComponent 51 @TbCoreComponent
52 @RequestMapping("/api") 52 @RequestMapping("/api")
53 -public class FirmwareController extends BaseController { 53 +public class OtaPackageController extends BaseController {
54 54
55 - public static final String FIRMWARE_ID = "firmwareId"; 55 + public static final String OTA_PACKAGE_ID = "otaPackageId";
56 public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm"; 56 public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm";
57 57
58 @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')") 58 @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
59 - @RequestMapping(value = "/firmware/{firmwareId}/download", method = RequestMethod.GET) 59 + @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET)
60 @ResponseBody 60 @ResponseBody
61 - public ResponseEntity<org.springframework.core.io.Resource> downloadFirmware(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {  
62 - checkParameter(FIRMWARE_ID, strFirmwareId); 61 + public ResponseEntity<org.springframework.core.io.Resource> downloadOtaPackage(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  62 + checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
63 try { 63 try {
64 - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));  
65 - Firmware firmware = checkFirmwareId(firmwareId, Operation.READ); 64 + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
  65 + OtaPackage otaPackage = checkOtaPackageId(otaPackageId, Operation.READ);
66 66
67 - ByteArrayResource resource = new ByteArrayResource(firmware.getData().array()); 67 + ByteArrayResource resource = new ByteArrayResource(otaPackage.getData().array());
68 return ResponseEntity.ok() 68 return ResponseEntity.ok()
69 - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmware.getFileName())  
70 - .header("x-filename", firmware.getFileName()) 69 + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackage.getFileName())
  70 + .header("x-filename", otaPackage.getFileName())
71 .contentLength(resource.contentLength()) 71 .contentLength(resource.contentLength())
72 - .contentType(parseMediaType(firmware.getContentType())) 72 + .contentType(parseMediaType(otaPackage.getContentType()))
73 .body(resource); 73 .body(resource);
74 } catch (Exception e) { 74 } catch (Exception e) {
75 throw handleException(e); 75 throw handleException(e);
@@ -77,144 +77,144 @@ public class FirmwareController extends BaseController { @@ -77,144 +77,144 @@ public class FirmwareController extends BaseController {
77 } 77 }
78 78
79 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 79 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
80 - @RequestMapping(value = "/firmware/info/{firmwareId}", method = RequestMethod.GET) 80 + @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET)
81 @ResponseBody 81 @ResponseBody
82 - public FirmwareInfo getFirmwareInfoById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {  
83 - checkParameter(FIRMWARE_ID, strFirmwareId); 82 + public OtaPackageInfo getOtaPackageInfoById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  83 + checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
84 try { 84 try {
85 - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));  
86 - return checkNotNull(firmwareService.findFirmwareInfoById(getTenantId(), firmwareId)); 85 + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
  86 + return checkNotNull(otaPackageService.findOtaPackageInfoById(getTenantId(), otaPackageId));
87 } catch (Exception e) { 87 } catch (Exception e) {
88 throw handleException(e); 88 throw handleException(e);
89 } 89 }
90 } 90 }
91 91
92 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 92 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
93 - @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.GET) 93 + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET)
94 @ResponseBody 94 @ResponseBody
95 - public Firmware getFirmwareById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {  
96 - checkParameter(FIRMWARE_ID, strFirmwareId); 95 + public OtaPackage getOtaPackageById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
  96 + checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
97 try { 97 try {
98 - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));  
99 - return checkFirmwareId(firmwareId, Operation.READ); 98 + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
  99 + return checkOtaPackageId(otaPackageId, Operation.READ);
100 } catch (Exception e) { 100 } catch (Exception e) {
101 throw handleException(e); 101 throw handleException(e);
102 } 102 }
103 } 103 }
104 104
105 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 105 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
106 - @RequestMapping(value = "/firmware", method = RequestMethod.POST) 106 + @RequestMapping(value = "/otaPackage", method = RequestMethod.POST)
107 @ResponseBody 107 @ResponseBody
108 - public FirmwareInfo saveFirmwareInfo(@RequestBody FirmwareInfo firmwareInfo) throws ThingsboardException {  
109 - boolean created = firmwareInfo.getId() == null; 108 + public OtaPackageInfo saveOtaPackageInfo(@RequestBody OtaPackageInfo otaPackageInfo) throws ThingsboardException {
  109 + boolean created = otaPackageInfo.getId() == null;
110 try { 110 try {
111 - firmwareInfo.setTenantId(getTenantId());  
112 - checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE);  
113 - FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo);  
114 - logEntityAction(savedFirmwareInfo.getId(), savedFirmwareInfo, 111 + otaPackageInfo.setTenantId(getTenantId());
  112 + checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE);
  113 + OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(otaPackageInfo);
  114 + logEntityAction(savedOtaPackageInfo.getId(), savedOtaPackageInfo,
115 null, created ? ActionType.ADDED : ActionType.UPDATED, null); 115 null, created ? ActionType.ADDED : ActionType.UPDATED, null);
116 - return savedFirmwareInfo; 116 + return savedOtaPackageInfo;
117 } catch (Exception e) { 117 } catch (Exception e) {
118 - logEntityAction(emptyId(EntityType.FIRMWARE), firmwareInfo, 118 + logEntityAction(emptyId(EntityType.OTA_PACKAGE), otaPackageInfo,
119 null, created ? ActionType.ADDED : ActionType.UPDATED, e); 119 null, created ? ActionType.ADDED : ActionType.UPDATED, e);
120 throw handleException(e); 120 throw handleException(e);
121 } 121 }
122 } 122 }
123 123
124 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 124 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
125 - @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.POST) 125 + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST)
126 @ResponseBody 126 @ResponseBody
127 - public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId,  
128 - @RequestParam(required = false) String checksum,  
129 - @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,  
130 - @RequestBody MultipartFile file) throws ThingsboardException {  
131 - checkParameter(FIRMWARE_ID, strFirmwareId); 127 + public OtaPackage saveOtaPackageData(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId,
  128 + @RequestParam(required = false) String checksum,
  129 + @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
  130 + @RequestBody MultipartFile file) throws ThingsboardException {
  131 + checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
132 checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr); 132 checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr);
133 try { 133 try {
134 - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));  
135 - FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.READ);  
136 -  
137 - Firmware firmware = new Firmware(firmwareId);  
138 - firmware.setCreatedTime(info.getCreatedTime());  
139 - firmware.setTenantId(getTenantId());  
140 - firmware.setDeviceProfileId(info.getDeviceProfileId());  
141 - firmware.setType(info.getType());  
142 - firmware.setTitle(info.getTitle());  
143 - firmware.setVersion(info.getVersion());  
144 - firmware.setAdditionalInfo(info.getAdditionalInfo()); 134 + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
  135 + OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.READ);
  136 +
  137 + OtaPackage otaPackage = new OtaPackage(otaPackageId);
  138 + otaPackage.setCreatedTime(info.getCreatedTime());
  139 + otaPackage.setTenantId(getTenantId());
  140 + otaPackage.setDeviceProfileId(info.getDeviceProfileId());
  141 + otaPackage.setType(info.getType());
  142 + otaPackage.setTitle(info.getTitle());
  143 + otaPackage.setVersion(info.getVersion());
  144 + otaPackage.setAdditionalInfo(info.getAdditionalInfo());
145 145
146 ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase()); 146 ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase());
147 147
148 byte[] bytes = file.getBytes(); 148 byte[] bytes = file.getBytes();
149 if (StringUtils.isEmpty(checksum)) { 149 if (StringUtils.isEmpty(checksum)) {
150 - checksum = firmwareService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes)); 150 + checksum = otaPackageService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes));
151 } 151 }
152 152
153 - firmware.setChecksumAlgorithm(checksumAlgorithm);  
154 - firmware.setChecksum(checksum);  
155 - firmware.setFileName(file.getOriginalFilename());  
156 - firmware.setContentType(file.getContentType());  
157 - firmware.setData(ByteBuffer.wrap(bytes));  
158 - firmware.setDataSize((long) bytes.length);  
159 - Firmware savedFirmware = firmwareService.saveFirmware(firmware);  
160 - logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null);  
161 - return savedFirmware; 153 + otaPackage.setChecksumAlgorithm(checksumAlgorithm);
  154 + otaPackage.setChecksum(checksum);
  155 + otaPackage.setFileName(file.getOriginalFilename());
  156 + otaPackage.setContentType(file.getContentType());
  157 + otaPackage.setData(ByteBuffer.wrap(bytes));
  158 + otaPackage.setDataSize((long) bytes.length);
  159 + OtaPackage savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage);
  160 + logEntityAction(savedOtaPackage.getId(), savedOtaPackage, null, ActionType.UPDATED, null);
  161 + return savedOtaPackage;
162 } catch (Exception e) { 162 } catch (Exception e) {
163 - logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.UPDATED, e, strFirmwareId); 163 + logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.UPDATED, e, strOtaPackageId);
164 throw handleException(e); 164 throw handleException(e);
165 } 165 }
166 } 166 }
167 167
168 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 168 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
169 - @RequestMapping(value = "/firmwares", method = RequestMethod.GET) 169 + @RequestMapping(value = "/otaPackages", method = RequestMethod.GET)
170 @ResponseBody 170 @ResponseBody
171 - public PageData<FirmwareInfo> getFirmwares(@RequestParam int pageSize,  
172 - @RequestParam int page,  
173 - @RequestParam(required = false) String textSearch,  
174 - @RequestParam(required = false) String sortProperty,  
175 - @RequestParam(required = false) String sortOrder) throws ThingsboardException { 171 + public PageData<OtaPackageInfo> getOtaPackages(@RequestParam int pageSize,
  172 + @RequestParam int page,
  173 + @RequestParam(required = false) String textSearch,
  174 + @RequestParam(required = false) String sortProperty,
  175 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
176 try { 176 try {
177 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 177 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
178 - return checkNotNull(firmwareService.findTenantFirmwaresByTenantId(getTenantId(), pageLink)); 178 + return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink));
179 } catch (Exception e) { 179 } catch (Exception e) {
180 throw handleException(e); 180 throw handleException(e);
181 } 181 }
182 } 182 }
183 183
184 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 184 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
185 - @RequestMapping(value = "/firmwares/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET) 185 + @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET)
186 @ResponseBody 186 @ResponseBody
187 - public PageData<FirmwareInfo> getFirmwares(@PathVariable("deviceProfileId") String strDeviceProfileId,  
188 - @PathVariable("type") String strType,  
189 - @PathVariable("hasData") boolean hasData,  
190 - @RequestParam int pageSize,  
191 - @RequestParam int page,  
192 - @RequestParam(required = false) String textSearch,  
193 - @RequestParam(required = false) String sortProperty,  
194 - @RequestParam(required = false) String sortOrder) throws ThingsboardException { 187 + public PageData<OtaPackageInfo> getOtaPackages(@PathVariable("deviceProfileId") String strDeviceProfileId,
  188 + @PathVariable("type") String strType,
  189 + @PathVariable("hasData") boolean hasData,
  190 + @RequestParam int pageSize,
  191 + @RequestParam int page,
  192 + @RequestParam(required = false) String textSearch,
  193 + @RequestParam(required = false) String sortProperty,
  194 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
195 checkParameter("deviceProfileId", strDeviceProfileId); 195 checkParameter("deviceProfileId", strDeviceProfileId);
196 checkParameter("type", strType); 196 checkParameter("type", strType);
197 try { 197 try {
198 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); 198 PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
199 - return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(),  
200 - new DeviceProfileId(toUUID(strDeviceProfileId)), FirmwareType.valueOf(strType), hasData, pageLink)); 199 + return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(),
  200 + new DeviceProfileId(toUUID(strDeviceProfileId)), OtaPackageType.valueOf(strType), hasData, pageLink));
201 } catch (Exception e) { 201 } catch (Exception e) {
202 throw handleException(e); 202 throw handleException(e);
203 } 203 }
204 } 204 }
205 205
206 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 206 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
207 - @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE) 207 + @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE)
208 @ResponseBody 208 @ResponseBody
209 - public void deleteFirmware(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException {  
210 - checkParameter(FIRMWARE_ID, strFirmwareId); 209 + public void deleteOtaPackage(@PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException {
  210 + checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
211 try { 211 try {
212 - FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));  
213 - FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.DELETE);  
214 - firmwareService.deleteFirmware(getTenantId(), firmwareId);  
215 - logEntityAction(firmwareId, info, null, ActionType.DELETED, null, strFirmwareId); 212 + OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
  213 + OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.DELETE);
  214 + otaPackageService.deleteOtaPackage(getTenantId(), otaPackageId);
  215 + logEntityAction(otaPackageId, info, null, ActionType.DELETED, null, strOtaPackageId);
216 } catch (Exception e) { 216 } catch (Exception e) {
217 - logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.DELETED, e, strFirmwareId); 217 + logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.DELETED, e, strOtaPackageId);
218 throw handleException(e); 218 throw handleException(e);
219 } 219 }
220 } 220 }
  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.action;
  17 +
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.fasterxml.jackson.databind.node.ArrayNode;
  20 +import com.fasterxml.jackson.databind.node.ObjectNode;
  21 +import lombok.RequiredArgsConstructor;
  22 +import lombok.extern.slf4j.Slf4j;
  23 +import org.apache.commons.lang3.StringUtils;
  24 +import org.springframework.stereotype.Service;
  25 +import org.thingsboard.server.common.data.DataConstants;
  26 +import org.thingsboard.server.common.data.EntityType;
  27 +import org.thingsboard.server.common.data.HasName;
  28 +import org.thingsboard.server.common.data.HasTenantId;
  29 +import org.thingsboard.server.common.data.User;
  30 +import org.thingsboard.server.common.data.audit.ActionType;
  31 +import org.thingsboard.server.common.data.id.CustomerId;
  32 +import org.thingsboard.server.common.data.id.EntityId;
  33 +import org.thingsboard.server.common.data.id.TenantId;
  34 +import org.thingsboard.server.common.data.kv.AttributeKvEntry;
  35 +import org.thingsboard.server.common.data.kv.DataType;
  36 +import org.thingsboard.server.common.data.kv.KvEntry;
  37 +import org.thingsboard.server.common.data.kv.TsKvEntry;
  38 +import org.thingsboard.server.common.msg.TbMsg;
  39 +import org.thingsboard.server.common.msg.TbMsgDataType;
  40 +import org.thingsboard.server.common.msg.TbMsgMetaData;
  41 +import org.thingsboard.server.queue.util.TbCoreComponent;
  42 +import org.thingsboard.server.service.queue.TbClusterService;
  43 +
  44 +import java.util.List;
  45 +import java.util.Map;
  46 +import java.util.stream.Collectors;
  47 +
  48 +@TbCoreComponent
  49 +@Service
  50 +@RequiredArgsConstructor
  51 +@Slf4j
  52 +public class RuleEngineEntityActionService {
  53 + private final TbClusterService tbClusterService;
  54 +
  55 + private static final ObjectMapper json = new ObjectMapper();
  56 +
  57 + public void pushEntityActionToRuleEngine(EntityId entityId, HasName entity, TenantId tenantId, CustomerId customerId,
  58 + ActionType actionType, User user, Object... additionalInfo) {
  59 + String msgType = null;
  60 + switch (actionType) {
  61 + case ADDED:
  62 + msgType = DataConstants.ENTITY_CREATED;
  63 + break;
  64 + case DELETED:
  65 + msgType = DataConstants.ENTITY_DELETED;
  66 + break;
  67 + case UPDATED:
  68 + msgType = DataConstants.ENTITY_UPDATED;
  69 + break;
  70 + case ASSIGNED_TO_CUSTOMER:
  71 + msgType = DataConstants.ENTITY_ASSIGNED;
  72 + break;
  73 + case UNASSIGNED_FROM_CUSTOMER:
  74 + msgType = DataConstants.ENTITY_UNASSIGNED;
  75 + break;
  76 + case ATTRIBUTES_UPDATED:
  77 + msgType = DataConstants.ATTRIBUTES_UPDATED;
  78 + break;
  79 + case ATTRIBUTES_DELETED:
  80 + msgType = DataConstants.ATTRIBUTES_DELETED;
  81 + break;
  82 + case ALARM_ACK:
  83 + msgType = DataConstants.ALARM_ACK;
  84 + break;
  85 + case ALARM_CLEAR:
  86 + msgType = DataConstants.ALARM_CLEAR;
  87 + break;
  88 + case ALARM_DELETE:
  89 + msgType = DataConstants.ALARM_DELETE;
  90 + break;
  91 + case ASSIGNED_FROM_TENANT:
  92 + msgType = DataConstants.ENTITY_ASSIGNED_FROM_TENANT;
  93 + break;
  94 + case ASSIGNED_TO_TENANT:
  95 + msgType = DataConstants.ENTITY_ASSIGNED_TO_TENANT;
  96 + break;
  97 + case PROVISION_SUCCESS:
  98 + msgType = DataConstants.PROVISION_SUCCESS;
  99 + break;
  100 + case PROVISION_FAILURE:
  101 + msgType = DataConstants.PROVISION_FAILURE;
  102 + break;
  103 + case TIMESERIES_UPDATED:
  104 + msgType = DataConstants.TIMESERIES_UPDATED;
  105 + break;
  106 + case TIMESERIES_DELETED:
  107 + msgType = DataConstants.TIMESERIES_DELETED;
  108 + break;
  109 + case ASSIGNED_TO_EDGE:
  110 + msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;
  111 + break;
  112 + case UNASSIGNED_FROM_EDGE:
  113 + msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;
  114 + break;
  115 + }
  116 + if (!StringUtils.isEmpty(msgType)) {
  117 + try {
  118 + TbMsgMetaData metaData = new TbMsgMetaData();
  119 + if (user != null) {
  120 + metaData.putValue("userId", user.getId().toString());
  121 + metaData.putValue("userName", user.getName());
  122 + }
  123 + if (customerId != null && !customerId.isNullUid()) {
  124 + metaData.putValue("customerId", customerId.toString());
  125 + }
  126 + if (actionType == ActionType.ASSIGNED_TO_CUSTOMER) {
  127 + String strCustomerId = extractParameter(String.class, 1, additionalInfo);
  128 + String strCustomerName = extractParameter(String.class, 2, additionalInfo);
  129 + metaData.putValue("assignedCustomerId", strCustomerId);
  130 + metaData.putValue("assignedCustomerName", strCustomerName);
  131 + } else if (actionType == ActionType.UNASSIGNED_FROM_CUSTOMER) {
  132 + String strCustomerId = extractParameter(String.class, 1, additionalInfo);
  133 + String strCustomerName = extractParameter(String.class, 2, additionalInfo);
  134 + metaData.putValue("unassignedCustomerId", strCustomerId);
  135 + metaData.putValue("unassignedCustomerName", strCustomerName);
  136 + } else if (actionType == ActionType.ASSIGNED_FROM_TENANT) {
  137 + String strTenantId = extractParameter(String.class, 0, additionalInfo);
  138 + String strTenantName = extractParameter(String.class, 1, additionalInfo);
  139 + metaData.putValue("assignedFromTenantId", strTenantId);
  140 + metaData.putValue("assignedFromTenantName", strTenantName);
  141 + } else if (actionType == ActionType.ASSIGNED_TO_TENANT) {
  142 + String strTenantId = extractParameter(String.class, 0, additionalInfo);
  143 + String strTenantName = extractParameter(String.class, 1, additionalInfo);
  144 + metaData.putValue("assignedToTenantId", strTenantId);
  145 + metaData.putValue("assignedToTenantName", strTenantName);
  146 + } else if (actionType == ActionType.ASSIGNED_TO_EDGE) {
  147 + String strEdgeId = extractParameter(String.class, 1, additionalInfo);
  148 + String strEdgeName = extractParameter(String.class, 2, additionalInfo);
  149 + metaData.putValue("assignedEdgeId", strEdgeId);
  150 + metaData.putValue("assignedEdgeName", strEdgeName);
  151 + } else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {
  152 + String strEdgeId = extractParameter(String.class, 1, additionalInfo);
  153 + String strEdgeName = extractParameter(String.class, 2, additionalInfo);
  154 + metaData.putValue("unassignedEdgeId", strEdgeId);
  155 + metaData.putValue("unassignedEdgeName", strEdgeName);
  156 + }
  157 + ObjectNode entityNode;
  158 + if (entity != null) {
  159 + entityNode = json.valueToTree(entity);
  160 + if (entityId.getEntityType() == EntityType.DASHBOARD) {
  161 + entityNode.put("configuration", "");
  162 + }
  163 + } else {
  164 + entityNode = json.createObjectNode();
  165 + if (actionType == ActionType.ATTRIBUTES_UPDATED) {
  166 + String scope = extractParameter(String.class, 0, additionalInfo);
  167 + @SuppressWarnings("unchecked")
  168 + List<AttributeKvEntry> attributes = extractParameter(List.class, 1, additionalInfo);
  169 + metaData.putValue(DataConstants.SCOPE, scope);
  170 + if (attributes != null) {
  171 + for (AttributeKvEntry attr : attributes) {
  172 + addKvEntry(entityNode, attr);
  173 + }
  174 + }
  175 + } else if (actionType == ActionType.ATTRIBUTES_DELETED) {
  176 + String scope = extractParameter(String.class, 0, additionalInfo);
  177 + @SuppressWarnings("unchecked")
  178 + List<String> keys = extractParameter(List.class, 1, additionalInfo);
  179 + metaData.putValue(DataConstants.SCOPE, scope);
  180 + ArrayNode attrsArrayNode = entityNode.putArray("attributes");
  181 + if (keys != null) {
  182 + keys.forEach(attrsArrayNode::add);
  183 + }
  184 + } else if (actionType == ActionType.TIMESERIES_UPDATED) {
  185 + @SuppressWarnings("unchecked")
  186 + List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);
  187 + addTimeseries(entityNode, timeseries);
  188 + } else if (actionType == ActionType.TIMESERIES_DELETED) {
  189 + @SuppressWarnings("unchecked")
  190 + List<String> keys = extractParameter(List.class, 0, additionalInfo);
  191 + if (keys != null) {
  192 + ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
  193 + keys.forEach(timeseriesArrayNode::add);
  194 + }
  195 + entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));
  196 + entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));
  197 + }
  198 + }
  199 + TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
  200 + if (tenantId.isNullUid()) {
  201 + if (entity instanceof HasTenantId) {
  202 + tenantId = ((HasTenantId) entity).getTenantId();
  203 + }
  204 + }
  205 + tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null);
  206 + } catch (Exception e) {
  207 + log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
  208 + }
  209 + }
  210 + }
  211 +
  212 +
  213 + private <T> T extractParameter(Class<T> clazz, int index, Object... additionalInfo) {
  214 + T result = null;
  215 + if (additionalInfo != null && additionalInfo.length > index) {
  216 + Object paramObject = additionalInfo[index];
  217 + if (clazz.isInstance(paramObject)) {
  218 + result = clazz.cast(paramObject);
  219 + }
  220 + }
  221 + return result;
  222 + }
  223 +
  224 + private void addTimeseries(ObjectNode entityNode, List<TsKvEntry> timeseries) throws Exception {
  225 + if (timeseries != null && !timeseries.isEmpty()) {
  226 + ArrayNode result = entityNode.putArray("timeseries");
  227 + Map<Long, List<TsKvEntry>> groupedTelemetry = timeseries.stream()
  228 + .collect(Collectors.groupingBy(TsKvEntry::getTs));
  229 + for (Map.Entry<Long, List<TsKvEntry>> entry : groupedTelemetry.entrySet()) {
  230 + ObjectNode element = json.createObjectNode();
  231 + element.put("ts", entry.getKey());
  232 + ObjectNode values = element.putObject("values");
  233 + for (TsKvEntry tsKvEntry : entry.getValue()) {
  234 + addKvEntry(values, tsKvEntry);
  235 + }
  236 + result.add(element);
  237 + }
  238 + }
  239 + }
  240 +
  241 + private void addKvEntry(ObjectNode entityNode, KvEntry kvEntry) throws Exception {
  242 + if (kvEntry.getDataType() == DataType.BOOLEAN) {
  243 + kvEntry.getBooleanValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
  244 + } else if (kvEntry.getDataType() == DataType.DOUBLE) {
  245 + kvEntry.getDoubleValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
  246 + } else if (kvEntry.getDataType() == DataType.LONG) {
  247 + kvEntry.getLongValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
  248 + } else if (kvEntry.getDataType() == DataType.JSON) {
  249 + if (kvEntry.getJsonValue().isPresent()) {
  250 + entityNode.set(kvEntry.getKey(), json.readTree(kvEntry.getJsonValue().get()));
  251 + }
  252 + } else {
  253 + entityNode.put(kvEntry.getKey(), kvEntry.getValueAsString());
  254 + }
  255 + }
  256 +}
application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java renamed from application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
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.firmware; 16 +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;
@@ -23,12 +23,9 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; @@ -23,12 +23,9 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
23 import org.thingsboard.server.common.data.DataConstants; 23 import org.thingsboard.server.common.data.DataConstants;
24 import org.thingsboard.server.common.data.Device; 24 import org.thingsboard.server.common.data.Device;
25 import org.thingsboard.server.common.data.DeviceProfile; 25 import org.thingsboard.server.common.data.DeviceProfile;
26 -import org.thingsboard.server.common.data.FirmwareInfo;  
27 -import org.thingsboard.server.common.data.firmware.FirmwareType;  
28 -import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;  
29 -import org.thingsboard.server.common.data.firmware.FirmwareUtil; 26 +import org.thingsboard.server.common.data.OtaPackageInfo;
30 import org.thingsboard.server.common.data.id.DeviceId; 27 import org.thingsboard.server.common.data.id.DeviceId;
31 -import org.thingsboard.server.common.data.id.FirmwareId; 28 +import org.thingsboard.server.common.data.id.OtaPackageId;
32 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.common.data.kv.AttributeKey; 30 import org.thingsboard.server.common.data.kv.AttributeKey;
34 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 31 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
@@ -37,13 +34,16 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -37,13 +34,16 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
37 import org.thingsboard.server.common.data.kv.LongDataEntry; 34 import org.thingsboard.server.common.data.kv.LongDataEntry;
38 import org.thingsboard.server.common.data.kv.StringDataEntry; 35 import org.thingsboard.server.common.data.kv.StringDataEntry;
39 import org.thingsboard.server.common.data.kv.TsKvEntry; 36 import org.thingsboard.server.common.data.kv.TsKvEntry;
  37 +import org.thingsboard.server.common.data.ota.OtaPackageType;
  38 +import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
  39 +import org.thingsboard.server.common.data.ota.OtaPackageUtil;
40 import org.thingsboard.server.common.data.page.PageData; 40 import org.thingsboard.server.common.data.page.PageData;
41 import org.thingsboard.server.common.data.page.PageLink; 41 import org.thingsboard.server.common.data.page.PageLink;
42 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; 42 import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
43 import org.thingsboard.server.dao.device.DeviceProfileService; 43 import org.thingsboard.server.dao.device.DeviceProfileService;
44 import org.thingsboard.server.dao.device.DeviceService; 44 import org.thingsboard.server.dao.device.DeviceService;
45 -import org.thingsboard.server.dao.firmware.FirmwareService;  
46 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 45 +import org.thingsboard.server.dao.ota.OtaPackageService;
  46 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
47 import org.thingsboard.server.queue.TbQueueProducer; 47 import org.thingsboard.server.queue.TbQueueProducer;
48 import org.thingsboard.server.queue.common.TbProtoQueueMsg; 48 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
49 import org.thingsboard.server.queue.provider.TbCoreQueueFactory; 49 import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
@@ -58,44 +58,43 @@ import java.util.List; @@ -58,44 +58,43 @@ import java.util.List;
58 import java.util.Set; 58 import java.util.Set;
59 import java.util.UUID; 59 import java.util.UUID;
60 import java.util.function.Consumer; 60 import java.util.function.Consumer;
61 -import java.util.function.Function;  
62 -  
63 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM;  
64 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM;  
65 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.SIZE;  
66 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE;  
67 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.TITLE;  
68 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.TS;  
69 -import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION;  
70 -import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;  
71 -import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE;  
72 -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey;  
73 -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTargetTelemetryKey;  
74 -import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTelemetryKey; 61 +
  62 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM;
  63 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM_ALGORITHM;
  64 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.SIZE;
  65 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE;
  66 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.TITLE;
  67 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.TS;
  68 +import static org.thingsboard.server.common.data.ota.OtaPackageKey.VERSION;
  69 +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
  70 +import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
  71 +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey;
  72 +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTargetTelemetryKey;
  73 +import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTelemetryKey;
75 74
76 @Slf4j 75 @Slf4j
77 @Service 76 @Service
78 @TbCoreComponent 77 @TbCoreComponent
79 -public class DefaultFirmwareStateService implements FirmwareStateService { 78 +public class DefaultOtaPackageStateService implements OtaPackageStateService {
80 79
81 private final TbClusterService tbClusterService; 80 private final TbClusterService tbClusterService;
82 - private final FirmwareService firmwareService; 81 + private final OtaPackageService otaPackageService;
83 private final DeviceService deviceService; 82 private final DeviceService deviceService;
84 private final DeviceProfileService deviceProfileService; 83 private final DeviceProfileService deviceProfileService;
85 private final RuleEngineTelemetryService telemetryService; 84 private final RuleEngineTelemetryService telemetryService;
86 - private final TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> fwStateMsgProducer; 85 + private final TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> otaPackageStateMsgProducer;
87 86
88 - public DefaultFirmwareStateService(TbClusterService tbClusterService, FirmwareService firmwareService,  
89 - DeviceService deviceService,  
90 - DeviceProfileService deviceProfileService,  
91 - RuleEngineTelemetryService telemetryService,  
92 - TbCoreQueueFactory coreQueueFactory) { 87 + public DefaultOtaPackageStateService(TbClusterService tbClusterService, OtaPackageService otaPackageService,
  88 + DeviceService deviceService,
  89 + DeviceProfileService deviceProfileService,
  90 + RuleEngineTelemetryService telemetryService,
  91 + TbCoreQueueFactory coreQueueFactory) {
93 this.tbClusterService = tbClusterService; 92 this.tbClusterService = tbClusterService;
94 - this.firmwareService = firmwareService; 93 + this.otaPackageService = otaPackageService;
95 this.deviceService = deviceService; 94 this.deviceService = deviceService;
96 this.deviceProfileService = deviceProfileService; 95 this.deviceProfileService = deviceProfileService;
97 this.telemetryService = telemetryService; 96 this.telemetryService = telemetryService;
98 - this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer(); 97 + this.otaPackageStateMsgProducer = coreQueueFactory.createToOtaPackageStateServiceMsgProducer();
99 } 98 }
100 99
101 @Override 100 @Override
@@ -105,14 +104,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -105,14 +104,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
105 } 104 }
106 105
107 private void updateFirmware(Device device, Device oldDevice) { 106 private void updateFirmware(Device device, Device oldDevice) {
108 - FirmwareId newFirmwareId = device.getFirmwareId(); 107 + OtaPackageId newFirmwareId = device.getFirmwareId();
109 if (newFirmwareId == null) { 108 if (newFirmwareId == null) {
110 DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); 109 DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
111 newFirmwareId = newDeviceProfile.getFirmwareId(); 110 newFirmwareId = newDeviceProfile.getFirmwareId();
112 } 111 }
113 if (oldDevice != null) { 112 if (oldDevice != null) {
114 if (newFirmwareId != null) { 113 if (newFirmwareId != null) {
115 - FirmwareId oldFirmwareId = oldDevice.getFirmwareId(); 114 + OtaPackageId oldFirmwareId = oldDevice.getFirmwareId();
116 if (oldFirmwareId == null) { 115 if (oldFirmwareId == null) {
117 DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); 116 DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId());
118 oldFirmwareId = oldDeviceProfile.getFirmwareId(); 117 oldFirmwareId = oldDeviceProfile.getFirmwareId();
@@ -132,14 +131,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -132,14 +131,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
132 } 131 }
133 132
134 private void updateSoftware(Device device, Device oldDevice) { 133 private void updateSoftware(Device device, Device oldDevice) {
135 - FirmwareId newSoftwareId = device.getSoftwareId(); 134 + OtaPackageId newSoftwareId = device.getSoftwareId();
136 if (newSoftwareId == null) { 135 if (newSoftwareId == null) {
137 DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); 136 DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
138 newSoftwareId = newDeviceProfile.getSoftwareId(); 137 newSoftwareId = newDeviceProfile.getSoftwareId();
139 } 138 }
140 if (oldDevice != null) { 139 if (oldDevice != null) {
141 if (newSoftwareId != null) { 140 if (newSoftwareId != null) {
142 - FirmwareId oldSoftwareId = oldDevice.getSoftwareId(); 141 + OtaPackageId oldSoftwareId = oldDevice.getSoftwareId();
143 if (oldSoftwareId == null) { 142 if (oldSoftwareId == null) {
144 DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); 143 DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId());
145 oldSoftwareId = oldDeviceProfile.getSoftwareId(); 144 oldSoftwareId = oldDeviceProfile.getSoftwareId();
@@ -170,33 +169,20 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -170,33 +169,20 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
170 } 169 }
171 } 170 }
172 171
173 - private void update(TenantId tenantId, DeviceProfile deviceProfile, FirmwareType firmwareType) {  
174 - Function<PageLink, PageData<Device>> getDevicesFunction; 172 + private void update(TenantId tenantId, DeviceProfile deviceProfile, OtaPackageType otaPackageType) {
175 Consumer<Device> updateConsumer; 173 Consumer<Device> updateConsumer;
176 174
177 - switch (firmwareType) {  
178 - case FIRMWARE:  
179 - getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pl);  
180 - break;  
181 - case SOFTWARE:  
182 - getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId, deviceProfile.getName(), pl);  
183 - break;  
184 - default:  
185 - log.warn("Unsupported firmware type: [{}]", firmwareType);  
186 - return;  
187 - }  
188 -  
189 if (deviceProfile.getFirmwareId() != null) { 175 if (deviceProfile.getFirmwareId() != null) {
190 long ts = System.currentTimeMillis(); 176 long ts = System.currentTimeMillis();
191 - updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, firmwareType); 177 + updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, otaPackageType);
192 } else { 178 } else {
193 - updateConsumer = d -> remove(d, firmwareType); 179 + updateConsumer = d -> remove(d, otaPackageType);
194 } 180 }
195 181
196 PageLink pageLink = new PageLink(100); 182 PageLink pageLink = new PageLink(100);
197 PageData<Device> pageData; 183 PageData<Device> pageData;
198 do { 184 do {
199 - pageData = getDevicesFunction.apply(pageLink); 185 + pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyOtaPackage(tenantId, deviceProfile.getId(), otaPackageType, pageLink);
200 pageData.getData().forEach(updateConsumer); 186 pageData.getData().forEach(updateConsumer);
201 187
202 if (pageData.hasNext()) { 188 if (pageData.hasNext()) {
@@ -206,60 +192,60 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -206,60 +192,60 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
206 } 192 }
207 193
208 @Override 194 @Override
209 - public boolean process(ToFirmwareStateServiceMsg msg) { 195 + public boolean process(ToOtaPackageStateServiceMsg msg) {
210 boolean isSuccess = false; 196 boolean isSuccess = false;
211 - FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB())); 197 + OtaPackageId targetOtaPackageId = new OtaPackageId(new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB()));
212 DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); 198 DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB()));
213 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); 199 TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
214 - FirmwareType firmwareType = FirmwareType.valueOf(msg.getType()); 200 + OtaPackageType firmwareType = OtaPackageType.valueOf(msg.getType());
215 long ts = msg.getTs(); 201 long ts = msg.getTs();
216 202
217 Device device = deviceService.findDeviceById(tenantId, deviceId); 203 Device device = deviceService.findDeviceById(tenantId, deviceId);
218 if (device == null) { 204 if (device == null) {
219 log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId); 205 log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId);
220 } else { 206 } else {
221 - FirmwareId currentFirmwareId = FirmwareUtil.getFirmwareId(device, firmwareType);  
222 - if (currentFirmwareId == null) { 207 + OtaPackageId currentOtaPackageId = OtaPackageUtil.getOtaPackageId(device, firmwareType);
  208 + if (currentOtaPackageId == null) {
223 DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()); 209 DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId());
224 - currentFirmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); 210 + currentOtaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, firmwareType);
225 } 211 }
226 212
227 - if (targetFirmwareId.equals(currentFirmwareId)) {  
228 - update(device, firmwareService.findFirmwareInfoById(device.getTenantId(), targetFirmwareId), ts); 213 + if (targetOtaPackageId.equals(currentOtaPackageId)) {
  214 + update(device, otaPackageService.findOtaPackageInfoById(device.getTenantId(), targetOtaPackageId), ts);
229 isSuccess = true; 215 isSuccess = true;
230 } else { 216 } else {
231 - log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetFirmwareId, currentFirmwareId); 217 + log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetOtaPackageId, currentOtaPackageId);
232 } 218 }
233 } 219 }
234 return isSuccess; 220 return isSuccess;
235 } 221 }
236 222
237 - private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts, FirmwareType firmwareType) {  
238 - ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder() 223 + private void send(TenantId tenantId, DeviceId deviceId, OtaPackageId firmwareId, long ts, OtaPackageType firmwareType) {
  224 + ToOtaPackageStateServiceMsg msg = ToOtaPackageStateServiceMsg.newBuilder()
239 .setTenantIdMSB(tenantId.getId().getMostSignificantBits()) 225 .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
240 .setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) 226 .setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
241 .setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) 227 .setDeviceIdMSB(deviceId.getId().getMostSignificantBits())
242 .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) 228 .setDeviceIdLSB(deviceId.getId().getLeastSignificantBits())
243 - .setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits())  
244 - .setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()) 229 + .setOtaPackageIdMSB(firmwareId.getId().getMostSignificantBits())
  230 + .setOtaPackageIdLSB(firmwareId.getId().getLeastSignificantBits())
245 .setType(firmwareType.name()) 231 .setType(firmwareType.name())
246 .setTs(ts) 232 .setTs(ts)
247 .build(); 233 .build();
248 234
249 - FirmwareInfo firmware = firmwareService.findFirmwareInfoById(tenantId, firmwareId); 235 + OtaPackageInfo firmware = otaPackageService.findOtaPackageInfoById(tenantId, firmwareId);
250 if (firmware == null) { 236 if (firmware == null) {
251 log.warn("[{}] Failed to send firmware update because firmware was already deleted", firmwareId); 237 log.warn("[{}] Failed to send firmware update because firmware was already deleted", firmwareId);
252 return; 238 return;
253 } 239 }
254 240
255 - TopicPartitionInfo tpi = new TopicPartitionInfo(fwStateMsgProducer.getDefaultTopic(), null, null, false);  
256 - fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null); 241 + TopicPartitionInfo tpi = new TopicPartitionInfo(otaPackageStateMsgProducer.getDefaultTopic(), null, null, false);
  242 + otaPackageStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
257 243
258 List<TsKvEntry> telemetry = new ArrayList<>(); 244 List<TsKvEntry> telemetry = new ArrayList<>();
259 telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle()))); 245 telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle())));
260 telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion()))); 246 telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion())));
261 telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts))); 247 telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts)));
262 - telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.QUEUED.name()))); 248 + telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.QUEUED.name())));
263 249
264 telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { 250 telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() {
265 @Override 251 @Override
@@ -275,11 +261,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -275,11 +261,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
275 } 261 }
276 262
277 263
278 - private void update(Device device, FirmwareInfo firmware, long ts) { 264 + private void update(Device device, OtaPackageInfo firmware, long ts) {
279 TenantId tenantId = device.getTenantId(); 265 TenantId tenantId = device.getTenantId();
280 DeviceId deviceId = device.getId(); 266 DeviceId deviceId = device.getId();
281 267
282 - BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.INITIATED.name())); 268 + BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.INITIATED.name()));
283 269
284 telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() { 270 telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() {
285 @Override 271 @Override
@@ -313,14 +299,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { @@ -313,14 +299,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
313 }); 299 });
314 } 300 }
315 301
316 - private void remove(Device device, FirmwareType firmwareType) {  
317 - telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareUtil.getAttributeKeys(firmwareType), 302 + private void remove(Device device, OtaPackageType firmwareType) {
  303 + telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, OtaPackageUtil.getAttributeKeys(firmwareType),
318 new FutureCallback<>() { 304 new FutureCallback<>() {
319 @Override 305 @Override
320 public void onSuccess(@Nullable Void tmp) { 306 public void onSuccess(@Nullable Void tmp) {
321 log.trace("[{}] Success remove target firmware attributes!", device.getId()); 307 log.trace("[{}] Success remove target firmware attributes!", device.getId());
322 Set<AttributeKey> keysToNotify = new HashSet<>(); 308 Set<AttributeKey> keysToNotify = new HashSet<>();
323 - FirmwareUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); 309 + OtaPackageUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key)));
324 tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null); 310 tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null);
325 } 311 }
326 312
application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java renamed from application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java
@@ -13,18 +13,18 @@ @@ -13,18 +13,18 @@
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.firmware; 16 +package org.thingsboard.server.service.ota;
17 17
18 import org.thingsboard.server.common.data.Device; 18 import org.thingsboard.server.common.data.Device;
19 import org.thingsboard.server.common.data.DeviceProfile; 19 import org.thingsboard.server.common.data.DeviceProfile;
20 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 20 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
21 21
22 -public interface FirmwareStateService { 22 +public interface OtaPackageStateService {
23 23
24 void update(Device device, Device oldDevice); 24 void update(Device device, Device oldDevice);
25 25
26 void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged); 26 void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged);
27 27
28 - boolean process(ToFirmwareStateServiceMsg msg); 28 + boolean process(ToOtaPackageStateServiceMsg msg);
29 29
30 } 30 }
@@ -50,7 +50,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseP @@ -50,7 +50,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseP
50 import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto; 50 import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto;
51 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 51 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
52 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 52 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
53 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 53 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
54 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; 54 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
55 import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; 55 import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
56 import org.thingsboard.server.queue.TbQueueConsumer; 56 import org.thingsboard.server.queue.TbQueueConsumer;
@@ -60,7 +60,7 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory; @@ -60,7 +60,7 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
60 import org.thingsboard.server.queue.util.TbCoreComponent; 60 import org.thingsboard.server.queue.util.TbCoreComponent;
61 import org.thingsboard.server.service.apiusage.TbApiUsageStateService; 61 import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
62 import org.thingsboard.server.service.edge.EdgeNotificationService; 62 import org.thingsboard.server.service.edge.EdgeNotificationService;
63 -import org.thingsboard.server.service.firmware.FirmwareStateService; 63 +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;
@@ -75,7 +75,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra @@ -75,7 +75,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra
75 75
76 import javax.annotation.PostConstruct; 76 import javax.annotation.PostConstruct;
77 import javax.annotation.PreDestroy; 77 import javax.annotation.PreDestroy;
78 -import java.util.ArrayList;  
79 import java.util.List; 78 import java.util.List;
80 import java.util.Optional; 79 import java.util.Optional;
81 import java.util.UUID; 80 import java.util.UUID;
@@ -101,9 +100,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -101,9 +100,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
101 @Value("${queue.core.stats.enabled:false}") 100 @Value("${queue.core.stats.enabled:false}")
102 private boolean statsEnabled; 101 private boolean statsEnabled;
103 102
104 - @Value("${queue.core.firmware.pack-interval-ms:60000}") 103 + @Value("${queue.core.ota.pack-interval-ms:60000}")
105 private long firmwarePackInterval; 104 private long firmwarePackInterval;
106 - @Value("${queue.core.firmware.pack-size:100}") 105 + @Value("${queue.core.ota.pack-size:100}")
107 private int firmwarePackSize; 106 private int firmwarePackSize;
108 107
109 private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> mainConsumer; 108 private final TbQueueConsumer<TbProtoQueueMsg<ToCoreMsg>> mainConsumer;
@@ -113,10 +112,10 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -113,10 +112,10 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
113 private final SubscriptionManagerService subscriptionManagerService; 112 private final SubscriptionManagerService subscriptionManagerService;
114 private final TbCoreDeviceRpcService tbCoreDeviceRpcService; 113 private final TbCoreDeviceRpcService tbCoreDeviceRpcService;
115 private final EdgeNotificationService edgeNotificationService; 114 private final EdgeNotificationService edgeNotificationService;
116 - private final FirmwareStateService firmwareStateService; 115 + private final OtaPackageStateService firmwareStateService;
117 private final TbCoreConsumerStats stats; 116 private final TbCoreConsumerStats stats;
118 protected final TbQueueConsumer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> usageStatsConsumer; 117 protected final TbQueueConsumer<TbProtoQueueMsg<ToUsageStatsServiceMsg>> usageStatsConsumer;
119 - private final TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> firmwareStatesConsumer; 118 + private final TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> firmwareStatesConsumer;
120 119
121 protected volatile ExecutorService usageStatsExecutor; 120 protected volatile ExecutorService usageStatsExecutor;
122 121
@@ -135,11 +134,11 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -135,11 +134,11 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
135 TbTenantProfileCache tenantProfileCache, 134 TbTenantProfileCache tenantProfileCache,
136 TbApiUsageStateService apiUsageStateService, 135 TbApiUsageStateService apiUsageStateService,
137 EdgeNotificationService edgeNotificationService, 136 EdgeNotificationService edgeNotificationService,
138 - FirmwareStateService firmwareStateService) { 137 + OtaPackageStateService firmwareStateService) {
139 super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, apiUsageStateService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); 138 super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, apiUsageStateService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer());
140 this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); 139 this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
141 this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer(); 140 this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer();
142 - this.firmwareStatesConsumer = tbCoreQueueFactory.createToFirmwareStateServiceMsgConsumer(); 141 + this.firmwareStatesConsumer = tbCoreQueueFactory.createToOtaPackageStateServiceMsgConsumer();
143 this.stateService = stateService; 142 this.stateService = stateService;
144 this.localSubscriptionService = localSubscriptionService; 143 this.localSubscriptionService = localSubscriptionService;
145 this.subscriptionManagerService = subscriptionManagerService; 144 this.subscriptionManagerService = subscriptionManagerService;
@@ -173,7 +172,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -173,7 +172,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
173 public void onApplicationEvent(ApplicationReadyEvent event) { 172 public void onApplicationEvent(ApplicationReadyEvent event) {
174 super.onApplicationEvent(event); 173 super.onApplicationEvent(event);
175 launchUsageStatsConsumer(); 174 launchUsageStatsConsumer();
176 - launchFirmwareUpdateNotificationConsumer(); 175 + launchOtaPackageUpdateNotificationConsumer();
177 } 176 }
178 177
179 @Override 178 @Override
@@ -361,20 +360,20 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -361,20 +360,20 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
361 }); 360 });
362 } 361 }
363 362
364 - private void launchFirmwareUpdateNotificationConsumer() { 363 + private void launchOtaPackageUpdateNotificationConsumer() {
365 long maxProcessingTimeoutPerRecord = firmwarePackInterval / firmwarePackSize; 364 long maxProcessingTimeoutPerRecord = firmwarePackInterval / firmwarePackSize;
366 firmwareStatesExecutor.submit(() -> { 365 firmwareStatesExecutor.submit(() -> {
367 while (!stopped) { 366 while (!stopped) {
368 try { 367 try {
369 - List<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration()); 368 + List<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration());
370 if (msgs.isEmpty()) { 369 if (msgs.isEmpty()) {
371 continue; 370 continue;
372 } 371 }
373 long timeToSleep = maxProcessingTimeoutPerRecord; 372 long timeToSleep = maxProcessingTimeoutPerRecord;
374 - for (TbProtoQueueMsg<ToFirmwareStateServiceMsg> msg : msgs) { 373 + for (TbProtoQueueMsg<ToOtaPackageStateServiceMsg> msg : msgs) {
375 try { 374 try {
376 long startTime = System.currentTimeMillis(); 375 long startTime = System.currentTimeMillis();
377 - boolean isSuccessUpdate = handleFirmwareUpdates(msg); 376 + boolean isSuccessUpdate = handleOtaPackageUpdates(msg);
378 long endTime = System.currentTimeMillis(); 377 long endTime = System.currentTimeMillis();
379 long spentTime = endTime - startTime; 378 long spentTime = endTime - startTime;
380 timeToSleep = timeToSleep - spentTime; 379 timeToSleep = timeToSleep - spentTime;
@@ -402,7 +401,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -402,7 +401,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
402 } 401 }
403 } 402 }
404 } 403 }
405 - log.info("TB Firmware States Consumer stopped."); 404 + log.info("TB Ota Package States Consumer stopped.");
406 }); 405 });
407 } 406 }
408 407
@@ -410,7 +409,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -410,7 +409,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
410 statsService.process(msg, callback); 409 statsService.process(msg, callback);
411 } 410 }
412 411
413 - private boolean handleFirmwareUpdates(TbProtoQueueMsg<ToFirmwareStateServiceMsg> msg) { 412 + private boolean handleOtaPackageUpdates(TbProtoQueueMsg<ToOtaPackageStateServiceMsg> msg) {
414 return firmwareStateService.process(msg.getValue()); 413 return firmwareStateService.process(msg.getValue());
415 } 414 }
416 415
@@ -89,7 +89,7 @@ public class DefaultTbResourceService implements TbResourceService { @@ -89,7 +89,7 @@ public class DefaultTbResourceService implements TbResourceService {
89 } catch (InvalidDDFFileException | IOException e) { 89 } catch (InvalidDDFFileException | IOException e) {
90 throw new ThingsboardException(e, ThingsboardErrorCode.GENERAL); 90 throw new ThingsboardException(e, ThingsboardErrorCode.GENERAL);
91 } 91 }
92 - if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource) == null) { 92 + if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource, true) == null) {
93 throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText())); 93 throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
94 } 94 }
95 } else { 95 } else {
@@ -131,7 +131,7 @@ public class DefaultTbResourceService implements TbResourceService { @@ -131,7 +131,7 @@ public class DefaultTbResourceService implements TbResourceService {
131 List<TbResource> resources = resourceService.findTenantResourcesByResourceTypeAndObjectIds(tenantId, ResourceType.LWM2M_MODEL, 131 List<TbResource> resources = resourceService.findTenantResourcesByResourceTypeAndObjectIds(tenantId, ResourceType.LWM2M_MODEL,
132 objectIds); 132 objectIds);
133 return resources.stream() 133 return resources.stream()
134 - .flatMap(s -> Stream.ofNullable(toLwM2mObject(s))) 134 + .flatMap(s -> Stream.ofNullable(toLwM2mObject(s, false)))
135 .sorted(getComparator(sortProperty, sortOrder)) 135 .sorted(getComparator(sortProperty, sortOrder))
136 .collect(Collectors.toList()); 136 .collect(Collectors.toList());
137 } 137 }
@@ -142,7 +142,7 @@ public class DefaultTbResourceService implements TbResourceService { @@ -142,7 +142,7 @@ public class DefaultTbResourceService implements TbResourceService {
142 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 142 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
143 PageData<TbResource> resourcePageData = resourceService.findTenantResourcesByResourceTypeAndPageLink(tenantId, ResourceType.LWM2M_MODEL, pageLink); 143 PageData<TbResource> resourcePageData = resourceService.findTenantResourcesByResourceTypeAndPageLink(tenantId, ResourceType.LWM2M_MODEL, pageLink);
144 return resourcePageData.getData().stream() 144 return resourcePageData.getData().stream()
145 - .flatMap(s -> Stream.ofNullable(toLwM2mObject(s))) 145 + .flatMap(s -> Stream.ofNullable(toLwM2mObject(s, false)))
146 .sorted(getComparator(sortProperty, sortOrder)) 146 .sorted(getComparator(sortProperty, sortOrder))
147 .collect(Collectors.toList()); 147 .collect(Collectors.toList());
148 } 148 }
@@ -167,7 +167,7 @@ public class DefaultTbResourceService implements TbResourceService { @@ -167,7 +167,7 @@ public class DefaultTbResourceService implements TbResourceService {
167 return "DESC".equals(sortOrder) ? comparator.reversed() : comparator; 167 return "DESC".equals(sortOrder) ? comparator.reversed() : comparator;
168 } 168 }
169 169
170 - private LwM2mObject toLwM2mObject(TbResource resource) { 170 + private LwM2mObject toLwM2mObject(TbResource resource, boolean isSave) {
171 try { 171 try {
172 DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator()); 172 DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
173 List<ObjectModel> objectModels = 173 List<ObjectModel> objectModels =
@@ -186,12 +186,16 @@ public class DefaultTbResourceService implements TbResourceService { @@ -186,12 +186,16 @@ public class DefaultTbResourceService implements TbResourceService {
186 instance.setId(0); 186 instance.setId(0);
187 List<LwM2mResourceObserve> resources = new ArrayList<>(); 187 List<LwM2mResourceObserve> resources = new ArrayList<>();
188 obj.resources.forEach((k, v) -> { 188 obj.resources.forEach((k, v) -> {
189 - if (v.operations.isReadable()) { 189 + if (isSave) {
  190 + LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false);
  191 + resources.add(lwM2MResourceObserve);
  192 + }
  193 + else if (v.operations.isReadable()) {
190 LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false); 194 LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false);
191 resources.add(lwM2MResourceObserve); 195 resources.add(lwM2MResourceObserve);
192 } 196 }
193 }); 197 });
194 - if (resources.size() > 0) { 198 + if (isSave || resources.size() > 0) {
195 instance.setResources(resources.toArray(LwM2mResourceObserve[]::new)); 199 instance.setResources(resources.toArray(LwM2mResourceObserve[]::new));
196 lwM2mObject.setInstances(new LwM2mInstance[]{instance}); 200 lwM2mObject.setInstances(new LwM2mInstance[]{instance});
197 return lwM2mObject; 201 return lwM2mObject;
@@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Customer; @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Customer;
30 import org.thingsboard.server.common.data.Device; 30 import org.thingsboard.server.common.data.Device;
31 import org.thingsboard.server.common.data.DeviceProfile; 31 import org.thingsboard.server.common.data.DeviceProfile;
32 import org.thingsboard.server.common.data.EntityView; 32 import org.thingsboard.server.common.data.EntityView;
33 -import org.thingsboard.server.common.data.FirmwareInfo; 33 +import org.thingsboard.server.common.data.OtaPackageInfo;
34 import org.thingsboard.server.common.data.TbResourceInfo; 34 import org.thingsboard.server.common.data.TbResourceInfo;
35 import org.thingsboard.server.common.data.Tenant; 35 import org.thingsboard.server.common.data.Tenant;
36 import org.thingsboard.server.common.data.User; 36 import org.thingsboard.server.common.data.User;
@@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
46 import org.thingsboard.server.common.data.id.EntityId; 46 import org.thingsboard.server.common.data.id.EntityId;
47 import org.thingsboard.server.common.data.id.EntityIdFactory; 47 import org.thingsboard.server.common.data.id.EntityIdFactory;
48 import org.thingsboard.server.common.data.id.EntityViewId; 48 import org.thingsboard.server.common.data.id.EntityViewId;
49 -import org.thingsboard.server.common.data.id.FirmwareId; 49 +import org.thingsboard.server.common.data.id.OtaPackageId;
50 import org.thingsboard.server.common.data.id.RuleChainId; 50 import org.thingsboard.server.common.data.id.RuleChainId;
51 import org.thingsboard.server.common.data.id.RuleNodeId; 51 import org.thingsboard.server.common.data.id.RuleNodeId;
52 import org.thingsboard.server.common.data.id.TbResourceId; 52 import org.thingsboard.server.common.data.id.TbResourceId;
@@ -63,7 +63,7 @@ import org.thingsboard.server.dao.device.DeviceService; @@ -63,7 +63,7 @@ import org.thingsboard.server.dao.device.DeviceService;
63 import org.thingsboard.server.dao.edge.EdgeService; 63 import org.thingsboard.server.dao.edge.EdgeService;
64 import org.thingsboard.server.dao.entityview.EntityViewService; 64 import org.thingsboard.server.dao.entityview.EntityViewService;
65 import org.thingsboard.server.dao.exception.IncorrectParameterException; 65 import org.thingsboard.server.dao.exception.IncorrectParameterException;
66 -import org.thingsboard.server.dao.firmware.FirmwareService; 66 +import org.thingsboard.server.dao.ota.OtaPackageService;
67 import org.thingsboard.server.dao.resource.ResourceService; 67 import org.thingsboard.server.dao.resource.ResourceService;
68 import org.thingsboard.server.dao.rule.RuleChainService; 68 import org.thingsboard.server.dao.rule.RuleChainService;
69 import org.thingsboard.server.dao.tenant.TenantService; 69 import org.thingsboard.server.dao.tenant.TenantService;
@@ -135,7 +135,7 @@ public class AccessValidator { @@ -135,7 +135,7 @@ public class AccessValidator {
135 protected ResourceService resourceService; 135 protected ResourceService resourceService;
136 136
137 @Autowired 137 @Autowired
138 - protected FirmwareService firmwareService; 138 + protected OtaPackageService otaPackageService;
139 139
140 private ExecutorService executor; 140 private ExecutorService executor;
141 141
@@ -232,8 +232,8 @@ public class AccessValidator { @@ -232,8 +232,8 @@ public class AccessValidator {
232 case TB_RESOURCE: 232 case TB_RESOURCE:
233 validateResource(currentUser, operation, entityId, callback); 233 validateResource(currentUser, operation, entityId, callback);
234 return; 234 return;
235 - case FIRMWARE:  
236 - validateFirmware(currentUser, operation, entityId, callback); 235 + case OTA_PACKAGE:
  236 + validateOtaPackage(currentUser, operation, entityId, callback);
237 return; 237 return;
238 default: 238 default:
239 //TODO: add support of other entities 239 //TODO: add support of other entities
@@ -300,20 +300,20 @@ public class AccessValidator { @@ -300,20 +300,20 @@ public class AccessValidator {
300 } 300 }
301 } 301 }
302 302
303 - private void validateFirmware(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) { 303 + private void validateOtaPackage(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
304 if (currentUser.isSystemAdmin()) { 304 if (currentUser.isSystemAdmin()) {
305 callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); 305 callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
306 } else { 306 } else {
307 - FirmwareInfo firmware = firmwareService.findFirmwareInfoById(currentUser.getTenantId(), new FirmwareId(entityId.getId()));  
308 - if (firmware == null) {  
309 - callback.onSuccess(ValidationResult.entityNotFound("Firmware with requested id wasn't found!")); 307 + OtaPackageInfo otaPackage = otaPackageService.findOtaPackageInfoById(currentUser.getTenantId(), new OtaPackageId(entityId.getId()));
  308 + if (otaPackage == null) {
  309 + callback.onSuccess(ValidationResult.entityNotFound("OtaPackage with requested id wasn't found!"));
310 } else { 310 } else {
311 try { 311 try {
312 - accessControlService.checkPermission(currentUser, Resource.FIRMWARE, operation, entityId, firmware); 312 + accessControlService.checkPermission(currentUser, Resource.OTA_PACKAGE, operation, entityId, otaPackage);
313 } catch (ThingsboardException e) { 313 } catch (ThingsboardException e) {
314 callback.onSuccess(ValidationResult.accessDenied(e.getMessage())); 314 callback.onSuccess(ValidationResult.accessDenied(e.getMessage()));
315 } 315 }
316 - callback.onSuccess(ValidationResult.ok(firmware)); 316 + callback.onSuccess(ValidationResult.ok(otaPackage));
317 } 317 }
318 } 318 }
319 } 319 }
@@ -38,7 +38,7 @@ public enum Resource { @@ -38,7 +38,7 @@ public enum Resource {
38 DEVICE_PROFILE(EntityType.DEVICE_PROFILE), 38 DEVICE_PROFILE(EntityType.DEVICE_PROFILE),
39 API_USAGE_STATE(EntityType.API_USAGE_STATE), 39 API_USAGE_STATE(EntityType.API_USAGE_STATE),
40 TB_RESOURCE(EntityType.TB_RESOURCE), 40 TB_RESOURCE(EntityType.TB_RESOURCE),
41 - FIRMWARE(EntityType.FIRMWARE), 41 + OTA_PACKAGE(EntityType.OTA_PACKAGE),
42 EDGE(EntityType.EDGE); 42 EDGE(EntityType.EDGE);
43 43
44 private final EntityType entityType; 44 private final EntityType entityType;
@@ -42,7 +42,7 @@ public class TenantAdminPermissions extends AbstractPermissions { @@ -42,7 +42,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
42 put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker); 42 put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker);
43 put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker); 43 put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker);
44 put(Resource.TB_RESOURCE, tbResourcePermissionChecker); 44 put(Resource.TB_RESOURCE, tbResourcePermissionChecker);
45 - put(Resource.FIRMWARE, tenantEntityPermissionChecker); 45 + put(Resource.OTA_PACKAGE, tenantEntityPermissionChecker);
46 put(Resource.EDGE, tenantEntityPermissionChecker); 46 put(Resource.EDGE, tenantEntityPermissionChecker);
47 } 47 }
48 48
@@ -26,27 +26,27 @@ import lombok.extern.slf4j.Slf4j; @@ -26,27 +26,27 @@ import lombok.extern.slf4j.Slf4j;
26 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
27 import org.springframework.util.StringUtils; 27 import org.springframework.util.StringUtils;
28 import org.thingsboard.common.util.JacksonUtil; 28 import org.thingsboard.common.util.JacksonUtil;
29 -import org.thingsboard.server.cache.firmware.FirmwareDataCache; 29 +import org.thingsboard.server.cache.ota.OtaPackageDataCache;
30 import org.thingsboard.server.common.data.ApiUsageState; 30 import org.thingsboard.server.common.data.ApiUsageState;
31 import org.thingsboard.server.common.data.DataConstants; 31 import org.thingsboard.server.common.data.DataConstants;
32 import org.thingsboard.server.common.data.Device; 32 import org.thingsboard.server.common.data.Device;
33 import org.thingsboard.server.common.data.DeviceProfile; 33 import org.thingsboard.server.common.data.DeviceProfile;
34 import org.thingsboard.server.common.data.DeviceTransportType; 34 import org.thingsboard.server.common.data.DeviceTransportType;
35 import org.thingsboard.server.common.data.EntityType; 35 import org.thingsboard.server.common.data.EntityType;
36 -import org.thingsboard.server.common.data.Firmware;  
37 -import org.thingsboard.server.common.data.FirmwareInfo; 36 +import org.thingsboard.server.common.data.OtaPackage;
  37 +import org.thingsboard.server.common.data.OtaPackageInfo;
38 import org.thingsboard.server.common.data.ResourceType; 38 import org.thingsboard.server.common.data.ResourceType;
39 import org.thingsboard.server.common.data.TbResource; 39 import org.thingsboard.server.common.data.TbResource;
40 import org.thingsboard.server.common.data.TenantProfile; 40 import org.thingsboard.server.common.data.TenantProfile;
41 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; 41 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
42 import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; 42 import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
43 import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; 43 import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
44 -import org.thingsboard.server.common.data.firmware.FirmwareType;  
45 -import org.thingsboard.server.common.data.firmware.FirmwareUtil; 44 +import org.thingsboard.server.common.data.ota.OtaPackageType;
  45 +import org.thingsboard.server.common.data.ota.OtaPackageUtil;
46 import org.thingsboard.server.common.data.id.CustomerId; 46 import org.thingsboard.server.common.data.id.CustomerId;
47 import org.thingsboard.server.common.data.id.DeviceId; 47 import org.thingsboard.server.common.data.id.DeviceId;
48 import org.thingsboard.server.common.data.id.DeviceProfileId; 48 import org.thingsboard.server.common.data.id.DeviceProfileId;
49 -import org.thingsboard.server.common.data.id.FirmwareId; 49 +import org.thingsboard.server.common.data.id.OtaPackageId;
50 import org.thingsboard.server.common.data.id.TenantId; 50 import org.thingsboard.server.common.data.id.TenantId;
51 import org.thingsboard.server.common.data.page.PageData; 51 import org.thingsboard.server.common.data.page.PageData;
52 import org.thingsboard.server.common.data.page.PageLink; 52 import org.thingsboard.server.common.data.page.PageLink;
@@ -64,7 +64,7 @@ import org.thingsboard.server.dao.device.DeviceService; @@ -64,7 +64,7 @@ import org.thingsboard.server.dao.device.DeviceService;
64 import org.thingsboard.server.dao.device.provision.ProvisionFailedException; 64 import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
65 import org.thingsboard.server.dao.device.provision.ProvisionRequest; 65 import org.thingsboard.server.dao.device.provision.ProvisionRequest;
66 import org.thingsboard.server.dao.device.provision.ProvisionResponse; 66 import org.thingsboard.server.dao.device.provision.ProvisionResponse;
67 -import org.thingsboard.server.dao.firmware.FirmwareService; 67 +import org.thingsboard.server.dao.ota.OtaPackageService;
68 import org.thingsboard.server.dao.relation.RelationService; 68 import org.thingsboard.server.dao.relation.RelationService;
69 import org.thingsboard.server.dao.tenant.TbTenantProfileCache; 69 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
70 import org.thingsboard.server.gen.transport.TransportProtos; 70 import org.thingsboard.server.gen.transport.TransportProtos;
@@ -124,8 +124,8 @@ public class DefaultTransportApiService implements TransportApiService { @@ -124,8 +124,8 @@ public class DefaultTransportApiService implements TransportApiService {
124 private final DataDecodingEncodingService dataDecodingEncodingService; 124 private final DataDecodingEncodingService dataDecodingEncodingService;
125 private final DeviceProvisionService deviceProvisionService; 125 private final DeviceProvisionService deviceProvisionService;
126 private final TbResourceService resourceService; 126 private final TbResourceService resourceService;
127 - private final FirmwareService firmwareService;  
128 - private final FirmwareDataCache firmwareDataCache; 127 + private final OtaPackageService otaPackageService;
  128 + private final OtaPackageDataCache otaPackageDataCache;
129 129
130 private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>(); 130 private final ConcurrentMap<String, ReentrantLock> deviceCreationLocks = new ConcurrentHashMap<>();
131 131
@@ -134,7 +134,7 @@ public class DefaultTransportApiService implements TransportApiService { @@ -134,7 +134,7 @@ public class DefaultTransportApiService implements TransportApiService {
134 RelationService relationService, DeviceCredentialsService deviceCredentialsService, 134 RelationService relationService, DeviceCredentialsService deviceCredentialsService,
135 DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService, 135 DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService,
136 TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService, 136 TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService,
137 - DeviceProvisionService deviceProvisionService, TbResourceService resourceService, FirmwareService firmwareService, FirmwareDataCache firmwareDataCache) { 137 + DeviceProvisionService deviceProvisionService, TbResourceService resourceService, OtaPackageService otaPackageService, OtaPackageDataCache otaPackageDataCache) {
138 this.deviceProfileCache = deviceProfileCache; 138 this.deviceProfileCache = deviceProfileCache;
139 this.tenantProfileCache = tenantProfileCache; 139 this.tenantProfileCache = tenantProfileCache;
140 this.apiUsageStateService = apiUsageStateService; 140 this.apiUsageStateService = apiUsageStateService;
@@ -147,8 +147,8 @@ public class DefaultTransportApiService implements TransportApiService { @@ -147,8 +147,8 @@ public class DefaultTransportApiService implements TransportApiService {
147 this.dataDecodingEncodingService = dataDecodingEncodingService; 147 this.dataDecodingEncodingService = dataDecodingEncodingService;
148 this.deviceProvisionService = deviceProvisionService; 148 this.deviceProvisionService = deviceProvisionService;
149 this.resourceService = resourceService; 149 this.resourceService = resourceService;
150 - this.firmwareService = firmwareService;  
151 - this.firmwareDataCache = firmwareDataCache; 150 + this.otaPackageService = otaPackageService;
  151 + this.otaPackageDataCache = otaPackageDataCache;
152 } 152 }
153 153
154 @Override 154 @Override
@@ -184,8 +184,8 @@ public class DefaultTransportApiService implements TransportApiService { @@ -184,8 +184,8 @@ public class DefaultTransportApiService implements TransportApiService {
184 result = handle(transportApiRequestMsg.getDeviceRequestMsg()); 184 result = handle(transportApiRequestMsg.getDeviceRequestMsg());
185 } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) { 185 } else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) {
186 result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg()); 186 result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg());
187 - } else if (transportApiRequestMsg.hasFirmwareRequestMsg()) {  
188 - result = handle(transportApiRequestMsg.getFirmwareRequestMsg()); 187 + } else if (transportApiRequestMsg.hasOtaPackageRequestMsg()) {
  188 + result = handle(transportApiRequestMsg.getOtaPackageRequestMsg());
189 } 189 }
190 190
191 return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture), 191 return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture),
@@ -511,50 +511,50 @@ public class DefaultTransportApiService implements TransportApiService { @@ -511,50 +511,50 @@ public class DefaultTransportApiService implements TransportApiService {
511 } 511 }
512 } 512 }
513 513
514 - private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.GetFirmwareRequestMsg requestMsg) { 514 + private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.GetOtaPackageRequestMsg requestMsg) {
515 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); 515 TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
516 DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB())); 516 DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB()));
517 - FirmwareType firmwareType = FirmwareType.valueOf(requestMsg.getType()); 517 + OtaPackageType otaPackageType = OtaPackageType.valueOf(requestMsg.getType());
518 Device device = deviceService.findDeviceById(tenantId, deviceId); 518 Device device = deviceService.findDeviceById(tenantId, deviceId);
519 519
520 if (device == null) { 520 if (device == null) {
521 return getEmptyTransportApiResponseFuture(); 521 return getEmptyTransportApiResponseFuture();
522 } 522 }
523 523
524 - FirmwareId firmwareId = FirmwareUtil.getFirmwareId(device, firmwareType);  
525 - if (firmwareId == null) { 524 + OtaPackageId otaPackageId = OtaPackageUtil.getOtaPackageId(device, otaPackageType);
  525 + if (otaPackageId == null) {
526 DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId()); 526 DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId());
527 - firmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType); 527 + otaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, otaPackageType);
528 } 528 }
529 529
530 - TransportProtos.GetFirmwareResponseMsg.Builder builder = TransportProtos.GetFirmwareResponseMsg.newBuilder(); 530 + TransportProtos.GetOtaPackageResponseMsg.Builder builder = TransportProtos.GetOtaPackageResponseMsg.newBuilder();
531 531
532 - if (firmwareId == null) { 532 + if (otaPackageId == null) {
533 builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); 533 builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND);
534 } else { 534 } else {
535 - FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(tenantId, firmwareId); 535 + OtaPackageInfo otaPackageInfo = otaPackageService.findOtaPackageInfoById(tenantId, otaPackageId);
536 536
537 - if (firmwareInfo == null) { 537 + if (otaPackageInfo == null) {
538 builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND); 538 builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND);
539 } else { 539 } else {
540 builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS); 540 builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS);
541 - builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits());  
542 - builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits());  
543 - builder.setType(firmwareInfo.getType().name());  
544 - builder.setTitle(firmwareInfo.getTitle());  
545 - builder.setVersion(firmwareInfo.getVersion());  
546 - builder.setFileName(firmwareInfo.getFileName());  
547 - builder.setContentType(firmwareInfo.getContentType());  
548 - if (!firmwareDataCache.has(firmwareId.toString())) {  
549 - Firmware firmware = firmwareService.findFirmwareById(tenantId, firmwareId);  
550 - firmwareDataCache.put(firmwareId.toString(), firmware.getData().array()); 541 + builder.setOtaPackageIdMSB(otaPackageId.getId().getMostSignificantBits());
  542 + builder.setOtaPackageIdLSB(otaPackageId.getId().getLeastSignificantBits());
  543 + builder.setType(otaPackageInfo.getType().name());
  544 + builder.setTitle(otaPackageInfo.getTitle());
  545 + builder.setVersion(otaPackageInfo.getVersion());
  546 + builder.setFileName(otaPackageInfo.getFileName());
  547 + builder.setContentType(otaPackageInfo.getContentType());
  548 + if (!otaPackageDataCache.has(otaPackageId.toString())) {
  549 + OtaPackage otaPackage = otaPackageService.findOtaPackageById(tenantId, otaPackageId);
  550 + otaPackageDataCache.put(otaPackageId.toString(), otaPackage.getData().array());
551 } 551 }
552 } 552 }
553 } 553 }
554 554
555 return Futures.immediateFuture( 555 return Futures.immediateFuture(
556 TransportApiResponseMsg.newBuilder() 556 TransportApiResponseMsg.newBuilder()
557 - .setFirmwareResponseMsg(builder.build()) 557 + .setOtaPackageResponseMsg(builder.build())
558 .build()); 558 .build());
559 } 559 }
560 560
@@ -17,9 +17,9 @@ package org.thingsboard.server.service.ttl; @@ -17,9 +17,9 @@ package org.thingsboard.server.service.ttl;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Value; 19 import org.springframework.beans.factory.annotation.Value;
20 -import org.thingsboard.server.dao.util.PsqlDao;  
21 20
22 import java.sql.Connection; 21 import java.sql.Connection;
  22 +import java.sql.DriverManager;
23 import java.sql.ResultSet; 23 import java.sql.ResultSet;
24 import java.sql.SQLException; 24 import java.sql.SQLException;
25 import java.sql.SQLWarning; 25 import java.sql.SQLWarning;
@@ -62,4 +62,8 @@ public abstract class AbstractCleanUpService { @@ -62,4 +62,8 @@ public abstract class AbstractCleanUpService {
62 62
63 protected abstract void doCleanUp(Connection connection) throws SQLException; 63 protected abstract void doCleanUp(Connection connection) throws SQLException;
64 64
  65 + protected Connection getConnection() throws SQLException {
  66 + return DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
  67 + }
  68 +
65 } 69 }
  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.ttl.alarms;
  17 +
  18 +import lombok.RequiredArgsConstructor;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.beans.factory.annotation.Value;
  21 +import org.springframework.scheduling.annotation.Scheduled;
  22 +import org.springframework.stereotype.Service;
  23 +import org.thingsboard.server.common.data.alarm.Alarm;
  24 +import org.thingsboard.server.common.data.audit.ActionType;
  25 +import org.thingsboard.server.common.data.id.AlarmId;
  26 +import org.thingsboard.server.common.data.id.TenantId;
  27 +import org.thingsboard.server.common.data.page.PageData;
  28 +import org.thingsboard.server.common.data.page.PageLink;
  29 +import org.thingsboard.server.common.data.page.SortOrder;
  30 +import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
  31 +import org.thingsboard.server.common.msg.queue.ServiceType;
  32 +import org.thingsboard.server.dao.alarm.AlarmDao;
  33 +import org.thingsboard.server.dao.alarm.AlarmService;
  34 +import org.thingsboard.server.dao.relation.RelationService;
  35 +import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
  36 +import org.thingsboard.server.dao.tenant.TenantDao;
  37 +import org.thingsboard.server.dao.util.PsqlDao;
  38 +import org.thingsboard.server.queue.discovery.PartitionService;
  39 +import org.thingsboard.server.queue.util.TbCoreComponent;
  40 +import org.thingsboard.server.service.action.RuleEngineEntityActionService;
  41 +import org.thingsboard.server.service.ttl.AbstractCleanUpService;
  42 +
  43 +import java.sql.Connection;
  44 +import java.sql.SQLException;
  45 +import java.util.Date;
  46 +import java.util.Optional;
  47 +import java.util.UUID;
  48 +import java.util.concurrent.TimeUnit;
  49 +
  50 +@TbCoreComponent
  51 +@Service
  52 +@Slf4j
  53 +@RequiredArgsConstructor
  54 +public class AlarmsCleanUpService {
  55 + @Value("${sql.ttl.alarms.removal_batch_size}")
  56 + private Integer removalBatchSize;
  57 +
  58 + private final TenantDao tenantDao;
  59 + private final AlarmDao alarmDao;
  60 + private final AlarmService alarmService;
  61 + private final RelationService relationService;
  62 + private final RuleEngineEntityActionService ruleEngineEntityActionService;
  63 + private final PartitionService partitionService;
  64 + private final TbTenantProfileCache tenantProfileCache;
  65 +
  66 + @Scheduled(initialDelayString = "#{T(org.apache.commons.lang3.RandomUtils).nextLong(0, ${sql.ttl.alarms.checking_interval})}", fixedDelayString = "${sql.ttl.alarms.checking_interval}")
  67 + public void cleanUp() {
  68 + PageLink tenantsBatchRequest = new PageLink(10_000, 0);
  69 + PageLink removalBatchRequest = new PageLink(removalBatchSize, 0 );
  70 + PageData<TenantId> tenantsIds;
  71 + do {
  72 + tenantsIds = tenantDao.findTenantsIds(tenantsBatchRequest);
  73 + for (TenantId tenantId : tenantsIds.getData()) {
  74 + if (!partitionService.resolve(ServiceType.TB_CORE, tenantId, tenantId).isMyPartition()) {
  75 + continue;
  76 + }
  77 +
  78 + Optional<DefaultTenantProfileConfiguration> tenantProfileConfiguration = tenantProfileCache.get(tenantId).getProfileConfiguration();
  79 + if (tenantProfileConfiguration.isEmpty() || tenantProfileConfiguration.get().getAlarmsTtlDays() == 0) {
  80 + continue;
  81 + }
  82 +
  83 + long ttl = TimeUnit.DAYS.toMillis(tenantProfileConfiguration.get().getAlarmsTtlDays());
  84 + long expirationTime = System.currentTimeMillis() - ttl;
  85 +
  86 + long totalRemoved = 0;
  87 + while (true) {
  88 + PageData<AlarmId> toRemove = alarmDao.findAlarmsIdsByEndTsBeforeAndTenantId(expirationTime, tenantId, removalBatchRequest);
  89 + toRemove.getData().forEach(alarmId -> {
  90 + relationService.deleteEntityRelations(tenantId, alarmId);
  91 + Alarm alarm = alarmService.deleteAlarm(tenantId, alarmId).getAlarm();
  92 + ruleEngineEntityActionService.pushEntityActionToRuleEngine(alarm.getOriginator(), alarm, tenantId, null, ActionType.ALARM_DELETE, null);
  93 + });
  94 +
  95 + totalRemoved += toRemove.getTotalElements();
  96 + if (!toRemove.hasNext()) {
  97 + break;
  98 + }
  99 + }
  100 +
  101 + if (totalRemoved > 0) {
  102 + log.info("Removed {} outdated alarm(s) for tenant {} older than {}", totalRemoved, tenantId, new Date(expirationTime));
  103 + }
  104 + }
  105 +
  106 + tenantsBatchRequest = tenantsBatchRequest.nextPageLink();
  107 + } while (tenantsIds.hasNext());
  108 + }
  109 +
  110 +}
@@ -40,7 +40,7 @@ public class EdgeEventsCleanUpService extends AbstractCleanUpService { @@ -40,7 +40,7 @@ public class EdgeEventsCleanUpService extends AbstractCleanUpService {
40 @Scheduled(initialDelayString = "${sql.ttl.edge_events.execution_interval_ms}", fixedDelayString = "${sql.ttl.edge_events.execution_interval_ms}") 40 @Scheduled(initialDelayString = "${sql.ttl.edge_events.execution_interval_ms}", fixedDelayString = "${sql.ttl.edge_events.execution_interval_ms}")
41 public void cleanUp() { 41 public void cleanUp() {
42 if (ttlTaskExecutionEnabled) { 42 if (ttlTaskExecutionEnabled) {
43 - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { 43 + try (Connection conn = getConnection()) {
44 doCleanUp(conn); 44 doCleanUp(conn);
45 } catch (SQLException e) { 45 } catch (SQLException e) {
46 log.error("SQLException occurred during TTL task execution ", e); 46 log.error("SQLException occurred during TTL task execution ", e);
@@ -43,7 +43,7 @@ public class EventsCleanUpService extends AbstractCleanUpService { @@ -43,7 +43,7 @@ public class EventsCleanUpService extends AbstractCleanUpService {
43 @Scheduled(initialDelayString = "${sql.ttl.events.execution_interval_ms}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}") 43 @Scheduled(initialDelayString = "${sql.ttl.events.execution_interval_ms}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}")
44 public void cleanUp() { 44 public void cleanUp() {
45 if (ttlTaskExecutionEnabled) { 45 if (ttlTaskExecutionEnabled) {
46 - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { 46 + try (Connection conn = getConnection()) {
47 doCleanUp(conn); 47 doCleanUp(conn);
48 } catch (SQLException e) { 48 } catch (SQLException e) {
49 log.error("SQLException occurred during TTL task execution ", e); 49 log.error("SQLException occurred during TTL task execution ", e);
@@ -36,7 +36,7 @@ public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpSe @@ -36,7 +36,7 @@ public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpSe
36 @Scheduled(initialDelayString = "${sql.ttl.ts.execution_interval_ms}", fixedDelayString = "${sql.ttl.ts.execution_interval_ms}") 36 @Scheduled(initialDelayString = "${sql.ttl.ts.execution_interval_ms}", fixedDelayString = "${sql.ttl.ts.execution_interval_ms}")
37 public void cleanUp() { 37 public void cleanUp() {
38 if (ttlTaskExecutionEnabled) { 38 if (ttlTaskExecutionEnabled) {
39 - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { 39 + try (Connection conn = getConnection()) {
40 doCleanUp(conn); 40 doCleanUp(conn);
41 } catch (SQLException e) { 41 } catch (SQLException e) {
42 log.error("SQLException occurred during TTL task execution ", e); 42 log.error("SQLException occurred during TTL task execution ", e);
@@ -273,6 +273,9 @@ sql: @@ -273,6 +273,9 @@ sql:
273 enabled: "${SQL_TTL_EDGE_EVENTS_ENABLED:true}" 273 enabled: "${SQL_TTL_EDGE_EVENTS_ENABLED:true}"
274 execution_interval_ms: "${SQL_TTL_EDGE_EVENTS_EXECUTION_INTERVAL:86400000}" # Number of milliseconds. The current value corresponds to one day 274 execution_interval_ms: "${SQL_TTL_EDGE_EVENTS_EXECUTION_INTERVAL:86400000}" # Number of milliseconds. The current value corresponds to one day
275 edge_events_ttl: "${SQL_TTL_EDGE_EVENTS_TTL:2628000}" # Number of seconds. The current value corresponds to one month 275 edge_events_ttl: "${SQL_TTL_EDGE_EVENTS_TTL:2628000}" # Number of seconds. The current value corresponds to one month
  276 + alarms:
  277 + checking_interval: "${SQL_ALARMS_TTL_CHECKING_INTERVAL:7200000}" # Number of milliseconds. The current value corresponds to two hours
  278 + removal_batch_size: "${SQL_ALARMS_TTL_REMOVAL_BATCH_SIZE:3000}" # To delete outdated alarms not all at once but in batches
276 279
277 # Actor system parameters 280 # Actor system parameters
278 actors: 281 actors:
@@ -371,7 +374,10 @@ caffeine: @@ -371,7 +374,10 @@ caffeine:
371 tokensOutdatageTime: 374 tokensOutdatageTime:
372 timeToLiveInMinutes: 20000 375 timeToLiveInMinutes: 20000
373 maxSize: 10000 376 maxSize: 10000
374 - firmwares: 377 + otaPackages:
  378 + timeToLiveInMinutes: 60
  379 + maxSize: 10
  380 + otaPackagesData:
375 timeToLiveInMinutes: 60 381 timeToLiveInMinutes: 60
376 maxSize: 10 382 maxSize: 10
377 edges: 383 edges:
@@ -497,7 +503,7 @@ audit-log: @@ -497,7 +503,7 @@ audit-log:
497 "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}" 503 "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}"
498 "edge": "${AUDIT_LOG_MASK_EDGE:W}" 504 "edge": "${AUDIT_LOG_MASK_EDGE:W}"
499 "tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}" 505 "tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}"
500 - "firmware": "${AUDIT_LOG_MASK_FIRMWARE:W}" 506 + "ota_package": "${AUDIT_LOG_MASK_OTA_PACKAGE:W}"
501 sink: 507 sink:
502 # Type of external sink. possible options: none, elasticsearch 508 # Type of external sink. possible options: none, elasticsearch
503 type: "${AUDIT_LOG_SINK_TYPE:none}" 509 type: "${AUDIT_LOG_SINK_TYPE:none}"
@@ -749,7 +755,7 @@ queue: @@ -749,7 +755,7 @@ queue:
749 sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}" 755 sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}"
750 security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}" 756 security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
751 consumer-properties-per-topic: 757 consumer-properties-per-topic:
752 - tb_firmware: 758 + tb_ota_package:
753 - key: max.poll.records 759 - key: max.poll.records
754 value: 10 760 value: 10
755 other: 761 other:
@@ -759,7 +765,7 @@ queue: @@ -759,7 +765,7 @@ queue:
759 transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" 765 transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
760 notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}" 766 notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
761 js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1}" 767 js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1}"
762 - fw-updates: "${TB_QUEUE_KAFKA_FW_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}" 768 + ota-updates: "${TB_QUEUE_KAFKA_OTA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}"
763 consumer-stats: 769 consumer-stats:
764 enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}" 770 enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}"
765 print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}" 771 print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}"
@@ -830,10 +836,10 @@ queue: @@ -830,10 +836,10 @@ queue:
830 poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}" 836 poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
831 partitions: "${TB_QUEUE_CORE_PARTITIONS:10}" 837 partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
832 pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}" 838 pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}"
833 - firmware:  
834 - topic: "${TB_QUEUE_CORE_FW_TOPIC:tb_firmware}"  
835 - pack-interval-ms: "${TB_QUEUE_CORE_FW_PACK_INTERVAL_MS:60000}"  
836 - pack-size: "${TB_QUEUE_CORE_FW_PACK_SIZE:100}" 839 + ota:
  840 + topic: "${TB_QUEUE_CORE_OTA_TOPIC:tb_ota_package}"
  841 + pack-interval-ms: "${TB_QUEUE_CORE_OTA_PACK_INTERVAL_MS:60000}"
  842 + pack-size: "${TB_QUEUE_CORE_OTA_PACK_SIZE:100}"
837 usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}" 843 usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
838 stats: 844 stats:
839 enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}" 845 enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}"
application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java renamed from application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java
@@ -25,11 +25,10 @@ import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequ @@ -25,11 +25,10 @@ import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequ
25 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 25 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
26 import org.thingsboard.common.util.JacksonUtil; 26 import org.thingsboard.common.util.JacksonUtil;
27 import org.thingsboard.server.common.data.DeviceProfile; 27 import org.thingsboard.server.common.data.DeviceProfile;
28 -import org.thingsboard.server.common.data.Firmware;  
29 -import org.thingsboard.server.common.data.FirmwareInfo; 28 +import org.thingsboard.server.common.data.OtaPackage;
  29 +import org.thingsboard.server.common.data.OtaPackageInfo;
30 import org.thingsboard.server.common.data.Tenant; 30 import org.thingsboard.server.common.data.Tenant;
31 import org.thingsboard.server.common.data.User; 31 import org.thingsboard.server.common.data.User;
32 -import org.thingsboard.server.common.data.firmware.FirmwareType;  
33 import org.thingsboard.server.common.data.id.DeviceProfileId; 32 import org.thingsboard.server.common.data.id.DeviceProfileId;
34 import org.thingsboard.server.common.data.page.PageData; 33 import org.thingsboard.server.common.data.page.PageData;
35 import org.thingsboard.server.common.data.page.PageLink; 34 import org.thingsboard.server.common.data.page.PageLink;
@@ -41,11 +40,11 @@ import java.util.Collections; @@ -41,11 +40,11 @@ import java.util.Collections;
41 import java.util.List; 40 import java.util.List;
42 41
43 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 42 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
44 -import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; 43 +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
45 44
46 -public abstract class BaseFirmwareControllerTest extends AbstractControllerTest { 45 +public abstract class BaseOtaPackageControllerTest extends AbstractControllerTest {
47 46
48 - private IdComparator<FirmwareInfo> idComparator = new IdComparator<>(); 47 + private IdComparator<OtaPackageInfo> idComparator = new IdComparator<>();
49 48
50 public static final String TITLE = "My firmware"; 49 public static final String TITLE = "My firmware";
51 private static final String FILE_NAME = "filename.txt"; 50 private static final String FILE_NAME = "filename.txt";
@@ -93,13 +92,13 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -93,13 +92,13 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
93 92
94 @Test 93 @Test
95 public void testSaveFirmware() throws Exception { 94 public void testSaveFirmware() throws Exception {
96 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 95 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
97 firmwareInfo.setDeviceProfileId(deviceProfileId); 96 firmwareInfo.setDeviceProfileId(deviceProfileId);
98 firmwareInfo.setType(FIRMWARE); 97 firmwareInfo.setType(FIRMWARE);
99 firmwareInfo.setTitle(TITLE); 98 firmwareInfo.setTitle(TITLE);
100 firmwareInfo.setVersion(VERSION); 99 firmwareInfo.setVersion(VERSION);
101 100
102 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 101 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
103 102
104 Assert.assertNotNull(savedFirmwareInfo); 103 Assert.assertNotNull(savedFirmwareInfo);
105 Assert.assertNotNull(savedFirmwareInfo.getId()); 104 Assert.assertNotNull(savedFirmwareInfo.getId());
@@ -112,19 +111,19 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -112,19 +111,19 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
112 111
113 save(savedFirmwareInfo); 112 save(savedFirmwareInfo);
114 113
115 - FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); 114 + OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
116 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); 115 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
117 } 116 }
118 117
119 @Test 118 @Test
120 public void testSaveFirmwareData() throws Exception { 119 public void testSaveFirmwareData() throws Exception {
121 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 120 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
122 firmwareInfo.setDeviceProfileId(deviceProfileId); 121 firmwareInfo.setDeviceProfileId(deviceProfileId);
123 firmwareInfo.setType(FIRMWARE); 122 firmwareInfo.setType(FIRMWARE);
124 firmwareInfo.setTitle(TITLE); 123 firmwareInfo.setTitle(TITLE);
125 firmwareInfo.setVersion(VERSION); 124 firmwareInfo.setVersion(VERSION);
126 125
127 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 126 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
128 127
129 Assert.assertNotNull(savedFirmwareInfo); 128 Assert.assertNotNull(savedFirmwareInfo);
130 Assert.assertNotNull(savedFirmwareInfo.getId()); 129 Assert.assertNotNull(savedFirmwareInfo.getId());
@@ -137,12 +136,12 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -137,12 +136,12 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
137 136
138 save(savedFirmwareInfo); 137 save(savedFirmwareInfo);
139 138
140 - FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); 139 + OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
141 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle()); 140 Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
142 141
143 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); 142 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
144 143
145 - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); 144 + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
146 145
147 Assert.assertEquals(FILE_NAME, savedFirmware.getFileName()); 146 Assert.assertEquals(FILE_NAME, savedFirmware.getFileName());
148 Assert.assertEquals(CONTENT_TYPE, savedFirmware.getContentType()); 147 Assert.assertEquals(CONTENT_TYPE, savedFirmware.getContentType());
@@ -150,97 +149,97 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -150,97 +149,97 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
150 149
151 @Test 150 @Test
152 public void testUpdateFirmwareFromDifferentTenant() throws Exception { 151 public void testUpdateFirmwareFromDifferentTenant() throws Exception {
153 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 152 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
154 firmwareInfo.setDeviceProfileId(deviceProfileId); 153 firmwareInfo.setDeviceProfileId(deviceProfileId);
155 firmwareInfo.setType(FIRMWARE); 154 firmwareInfo.setType(FIRMWARE);
156 firmwareInfo.setTitle(TITLE); 155 firmwareInfo.setTitle(TITLE);
157 firmwareInfo.setVersion(VERSION); 156 firmwareInfo.setVersion(VERSION);
158 157
159 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 158 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
160 159
161 loginDifferentTenant(); 160 loginDifferentTenant();
162 - doPost("/api/firmware", savedFirmwareInfo, FirmwareInfo.class, status().isForbidden()); 161 + doPost("/api/otaPackage", savedFirmwareInfo, OtaPackageInfo.class, status().isForbidden());
163 deleteDifferentTenant(); 162 deleteDifferentTenant();
164 } 163 }
165 164
166 @Test 165 @Test
167 public void testFindFirmwareInfoById() throws Exception { 166 public void testFindFirmwareInfoById() throws Exception {
168 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 167 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
169 firmwareInfo.setDeviceProfileId(deviceProfileId); 168 firmwareInfo.setDeviceProfileId(deviceProfileId);
170 firmwareInfo.setType(FIRMWARE); 169 firmwareInfo.setType(FIRMWARE);
171 firmwareInfo.setTitle(TITLE); 170 firmwareInfo.setTitle(TITLE);
172 firmwareInfo.setVersion(VERSION); 171 firmwareInfo.setVersion(VERSION);
173 172
174 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 173 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
175 174
176 - FirmwareInfo foundFirmware = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class); 175 + OtaPackageInfo foundFirmware = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
177 Assert.assertNotNull(foundFirmware); 176 Assert.assertNotNull(foundFirmware);
178 Assert.assertEquals(savedFirmwareInfo, foundFirmware); 177 Assert.assertEquals(savedFirmwareInfo, foundFirmware);
179 } 178 }
180 179
181 @Test 180 @Test
182 public void testFindFirmwareById() throws Exception { 181 public void testFindFirmwareById() throws Exception {
183 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 182 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
184 firmwareInfo.setDeviceProfileId(deviceProfileId); 183 firmwareInfo.setDeviceProfileId(deviceProfileId);
185 firmwareInfo.setType(FIRMWARE); 184 firmwareInfo.setType(FIRMWARE);
186 firmwareInfo.setTitle(TITLE); 185 firmwareInfo.setTitle(TITLE);
187 firmwareInfo.setVersion(VERSION); 186 firmwareInfo.setVersion(VERSION);
188 187
189 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 188 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
190 189
191 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); 190 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
192 191
193 - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM); 192 + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
194 193
195 - Firmware foundFirmware = doGet("/api/firmware/" + savedFirmwareInfo.getId().getId().toString(), Firmware.class); 194 + OtaPackage foundFirmware = doGet("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString(), OtaPackage.class);
196 Assert.assertNotNull(foundFirmware); 195 Assert.assertNotNull(foundFirmware);
197 Assert.assertEquals(savedFirmware, foundFirmware); 196 Assert.assertEquals(savedFirmware, foundFirmware);
198 } 197 }
199 198
200 @Test 199 @Test
201 public void testDeleteFirmware() throws Exception { 200 public void testDeleteFirmware() throws Exception {
202 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 201 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
203 firmwareInfo.setDeviceProfileId(deviceProfileId); 202 firmwareInfo.setDeviceProfileId(deviceProfileId);
204 firmwareInfo.setType(FIRMWARE); 203 firmwareInfo.setType(FIRMWARE);
205 firmwareInfo.setTitle(TITLE); 204 firmwareInfo.setTitle(TITLE);
206 firmwareInfo.setVersion(VERSION); 205 firmwareInfo.setVersion(VERSION);
207 206
208 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 207 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
209 208
210 - doDelete("/api/firmware/" + savedFirmwareInfo.getId().getId().toString()) 209 + doDelete("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString())
211 .andExpect(status().isOk()); 210 .andExpect(status().isOk());
212 211
213 - doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString()) 212 + doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString())
214 .andExpect(status().isNotFound()); 213 .andExpect(status().isNotFound());
215 } 214 }
216 215
217 @Test 216 @Test
218 public void testFindTenantFirmwares() throws Exception { 217 public void testFindTenantFirmwares() throws Exception {
219 - List<FirmwareInfo> firmwares = new ArrayList<>(); 218 + List<OtaPackageInfo> otaPackages = new ArrayList<>();
220 for (int i = 0; i < 165; i++) { 219 for (int i = 0; i < 165; i++) {
221 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 220 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
222 firmwareInfo.setDeviceProfileId(deviceProfileId); 221 firmwareInfo.setDeviceProfileId(deviceProfileId);
223 firmwareInfo.setType(FIRMWARE); 222 firmwareInfo.setType(FIRMWARE);
224 firmwareInfo.setTitle(TITLE); 223 firmwareInfo.setTitle(TITLE);
225 firmwareInfo.setVersion(VERSION + i); 224 firmwareInfo.setVersion(VERSION + i);
226 225
227 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 226 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
228 227
229 if (i > 100) { 228 if (i > 100) {
230 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); 229 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
231 230
232 - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);  
233 - firmwares.add(new FirmwareInfo(savedFirmware)); 231 + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
  232 + otaPackages.add(new OtaPackageInfo(savedFirmware));
234 } else { 233 } else {
235 - firmwares.add(savedFirmwareInfo); 234 + otaPackages.add(savedFirmwareInfo);
236 } 235 }
237 } 236 }
238 237
239 - List<FirmwareInfo> loadedFirmwares = new ArrayList<>(); 238 + List<OtaPackageInfo> loadedFirmwares = new ArrayList<>();
240 PageLink pageLink = new PageLink(24); 239 PageLink pageLink = new PageLink(24);
241 - PageData<FirmwareInfo> pageData; 240 + PageData<OtaPackageInfo> pageData;
242 do { 241 do {
243 - pageData = doGetTypedWithPageLink("/api/firmwares?", 242 + pageData = doGetTypedWithPageLink("/api/otaPackages?",
244 new TypeReference<>() { 243 new TypeReference<>() {
245 }, pageLink); 244 }, pageLink);
246 loadedFirmwares.addAll(pageData.getData()); 245 loadedFirmwares.addAll(pageData.getData());
@@ -249,41 +248,41 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -249,41 +248,41 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
249 } 248 }
250 } while (pageData.hasNext()); 249 } while (pageData.hasNext());
251 250
252 - Collections.sort(firmwares, idComparator); 251 + Collections.sort(otaPackages, idComparator);
253 Collections.sort(loadedFirmwares, idComparator); 252 Collections.sort(loadedFirmwares, idComparator);
254 253
255 - Assert.assertEquals(firmwares, loadedFirmwares); 254 + Assert.assertEquals(otaPackages, loadedFirmwares);
256 } 255 }
257 256
258 @Test 257 @Test
259 public void testFindTenantFirmwaresByHasData() throws Exception { 258 public void testFindTenantFirmwaresByHasData() throws Exception {
260 - List<FirmwareInfo> firmwaresWithData = new ArrayList<>();  
261 - List<FirmwareInfo> firmwaresWithoutData = new ArrayList<>(); 259 + List<OtaPackageInfo> otaPackagesWithData = new ArrayList<>();
  260 + List<OtaPackageInfo> otaPackagesWithoutData = new ArrayList<>();
262 261
263 for (int i = 0; i < 165; i++) { 262 for (int i = 0; i < 165; i++) {
264 - FirmwareInfo firmwareInfo = new FirmwareInfo(); 263 + OtaPackageInfo firmwareInfo = new OtaPackageInfo();
265 firmwareInfo.setDeviceProfileId(deviceProfileId); 264 firmwareInfo.setDeviceProfileId(deviceProfileId);
266 firmwareInfo.setType(FIRMWARE); 265 firmwareInfo.setType(FIRMWARE);
267 firmwareInfo.setTitle(TITLE); 266 firmwareInfo.setTitle(TITLE);
268 firmwareInfo.setVersion(VERSION + i); 267 firmwareInfo.setVersion(VERSION + i);
269 268
270 - FirmwareInfo savedFirmwareInfo = save(firmwareInfo); 269 + OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
271 270
272 if (i > 100) { 271 if (i > 100) {
273 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array()); 272 MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
274 273
275 - Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);  
276 - firmwaresWithData.add(new FirmwareInfo(savedFirmware)); 274 + OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
  275 + otaPackagesWithData.add(new OtaPackageInfo(savedFirmware));
277 } else { 276 } else {
278 - firmwaresWithoutData.add(savedFirmwareInfo); 277 + otaPackagesWithoutData.add(savedFirmwareInfo);
279 } 278 }
280 } 279 }
281 280
282 - List<FirmwareInfo> loadedFirmwaresWithData = new ArrayList<>(); 281 + List<OtaPackageInfo> loadedFirmwaresWithData = new ArrayList<>();
283 PageLink pageLink = new PageLink(24); 282 PageLink pageLink = new PageLink(24);
284 - PageData<FirmwareInfo> pageData; 283 + PageData<OtaPackageInfo> pageData;
285 do { 284 do {
286 - pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/true?", 285 + pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/true?",
287 new TypeReference<>() { 286 new TypeReference<>() {
288 }, pageLink); 287 }, pageLink);
289 loadedFirmwaresWithData.addAll(pageData.getData()); 288 loadedFirmwaresWithData.addAll(pageData.getData());
@@ -292,10 +291,10 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -292,10 +291,10 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
292 } 291 }
293 } while (pageData.hasNext()); 292 } while (pageData.hasNext());
294 293
295 - List<FirmwareInfo> loadedFirmwaresWithoutData = new ArrayList<>(); 294 + List<OtaPackageInfo> loadedFirmwaresWithoutData = new ArrayList<>();
296 pageLink = new PageLink(24); 295 pageLink = new PageLink(24);
297 do { 296 do {
298 - pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/false?", 297 + pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/false?",
299 new TypeReference<>() { 298 new TypeReference<>() {
300 }, pageLink); 299 }, pageLink);
301 loadedFirmwaresWithoutData.addAll(pageData.getData()); 300 loadedFirmwaresWithoutData.addAll(pageData.getData());
@@ -304,25 +303,25 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest @@ -304,25 +303,25 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
304 } 303 }
305 } while (pageData.hasNext()); 304 } while (pageData.hasNext());
306 305
307 - Collections.sort(firmwaresWithData, idComparator);  
308 - Collections.sort(firmwaresWithoutData, idComparator); 306 + Collections.sort(otaPackagesWithData, idComparator);
  307 + Collections.sort(otaPackagesWithoutData, idComparator);
309 Collections.sort(loadedFirmwaresWithData, idComparator); 308 Collections.sort(loadedFirmwaresWithData, idComparator);
310 Collections.sort(loadedFirmwaresWithoutData, idComparator); 309 Collections.sort(loadedFirmwaresWithoutData, idComparator);
311 310
312 - Assert.assertEquals(firmwaresWithData, loadedFirmwaresWithData);  
313 - Assert.assertEquals(firmwaresWithoutData, loadedFirmwaresWithoutData); 311 + Assert.assertEquals(otaPackagesWithData, loadedFirmwaresWithData);
  312 + Assert.assertEquals(otaPackagesWithoutData, loadedFirmwaresWithoutData);
314 } 313 }
315 314
316 315
317 - private FirmwareInfo save(FirmwareInfo firmwareInfo) throws Exception {  
318 - return doPost("/api/firmware", firmwareInfo, FirmwareInfo.class); 316 + private OtaPackageInfo save(OtaPackageInfo firmwareInfo) throws Exception {
  317 + return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class);
319 } 318 }
320 319
321 - protected Firmware savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception { 320 + protected OtaPackage savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception {
322 MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params); 321 MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params);
323 postRequest.file(content); 322 postRequest.file(content);
324 setJwtToken(postRequest); 323 setJwtToken(postRequest);
325 - return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), Firmware.class); 324 + return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), OtaPackage.class);
326 } 325 }
327 326
328 } 327 }
application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java renamed from application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java
@@ -15,9 +15,9 @@ @@ -15,9 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.controller.sql; 16 package org.thingsboard.server.controller.sql;
17 17
18 -import org.thingsboard.server.controller.BaseFirmwareControllerTest; 18 +import org.thingsboard.server.controller.BaseOtaPackageControllerTest;
19 import org.thingsboard.server.dao.service.DaoSqlTest; 19 import org.thingsboard.server.dao.service.DaoSqlTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class FirmwareControllerSqlTest extends BaseFirmwareControllerTest { 22 +public class OtaPackageControllerSqlTest extends BaseOtaPackageControllerTest {
23 } 23 }
@@ -44,6 +44,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr @@ -44,6 +44,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
44 44
45 private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}"; 45 private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}";
46 46
  47 + protected static final String POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION = "{\"attribute1\":\"value\",\"attribute2\":false,\"attribute3\":41.0,\"attribute4\":72," +
  48 + "\"attribute5\":{\"someNumber\":41,\"someArray\":[],\"someNestedObject\":{\"key\":\"value\"}}}";
  49 +
47 @Before 50 @Before
48 public void beforeTest() throws Exception { 51 public void beforeTest() throws Exception {
49 processBeforeTest("Test Subscribe to attribute updates", null, null); 52 processBeforeTest("Test Subscribe to attribute updates", null, null);
@@ -56,50 +59,85 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr @@ -56,50 +59,85 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
56 59
57 @Test 60 @Test
58 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception { 61 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
59 - processTestSubscribeToAttributesUpdates(); 62 + processTestSubscribeToAttributesUpdates(false);
60 } 63 }
61 64
62 - protected void processTestSubscribeToAttributesUpdates() throws Exception { 65 + @Test
  66 + public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
  67 + processTestSubscribeToAttributesUpdates(true);
  68 + }
63 69
  70 + protected void processTestSubscribeToAttributesUpdates(boolean emptyCurrentStateNotification) throws Exception {
  71 + if (!emptyCurrentStateNotification) {
  72 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION, String.class, status().isOk());
  73 + }
64 CoapClient client = getCoapClient(FeatureType.ATTRIBUTES); 74 CoapClient client = getCoapClient(FeatureType.ATTRIBUTES);
65 75
66 CountDownLatch latch = new CountDownLatch(1); 76 CountDownLatch latch = new CountDownLatch(1);
67 - TestCoapCallback testCoapCallback = new TestCoapCallback(latch); 77 + TestCoapCallback callback = new TestCoapCallback(latch);
68 78
69 Request request = Request.newGet().setObserve(); 79 Request request = Request.newGet().setObserve();
70 request.setType(CoAP.Type.CON); 80 request.setType(CoAP.Type.CON);
71 - CoapObserveRelation observeRelation = client.observe(request, testCoapCallback); 81 + CoapObserveRelation observeRelation = client.observe(request, callback);
72 82
73 - Thread.sleep(1000); 83 + latch.await(3, TimeUnit.SECONDS);
  84 +
  85 + if (emptyCurrentStateNotification) {
  86 + validateEmptyCurrentStateAttributesResponse(callback);
  87 + } else {
  88 + validateCurrentStateAttributesResponse(callback);
  89 + }
  90 +
  91 + latch = new CountDownLatch(1);
74 92
75 doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); 93 doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
76 latch.await(3, TimeUnit.SECONDS); 94 latch.await(3, TimeUnit.SECONDS);
77 95
78 - validateUpdateAttributesResponse(testCoapCallback); 96 + validateUpdateAttributesResponse(callback);
79 97
80 latch = new CountDownLatch(1); 98 latch = new CountDownLatch(1);
81 99
82 doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class); 100 doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
83 latch.await(3, TimeUnit.SECONDS); 101 latch.await(3, TimeUnit.SECONDS);
84 102
85 - validateDeleteAttributesResponse(testCoapCallback); 103 + validateDeleteAttributesResponse(callback);
86 104
87 observeRelation.proactiveCancel(); 105 observeRelation.proactiveCancel();
88 assertTrue(observeRelation.isCanceled()); 106 assertTrue(observeRelation.isCanceled());
89 } 107 }
90 108
91 - protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException { 109 + protected void validateCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
  110 + assertNotNull(callback.getPayloadBytes());
  111 + assertNotNull(callback.getObserve());
  112 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  113 + assertEquals(0, callback.getObserve().intValue());
  114 + String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  115 + assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION), JacksonUtil.toJsonNode(response));
  116 + }
  117 +
  118 + protected void validateEmptyCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
92 assertNotNull(callback.getPayloadBytes()); 119 assertNotNull(callback.getPayloadBytes());
93 assertNotNull(callback.getObserve()); 120 assertNotNull(callback.getObserve());
  121 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
94 assertEquals(0, callback.getObserve().intValue()); 122 assertEquals(0, callback.getObserve().intValue());
95 String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); 123 String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  124 + assertEquals("{}", response);
  125 + }
  126 +
  127 + protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
  128 + assertNotNull(callback.getPayloadBytes());
  129 + assertNotNull(callback.getObserve());
  130 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  131 + assertEquals(1, callback.getObserve().intValue());
  132 + String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
96 assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response)); 133 assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response));
97 } 134 }
98 135
99 protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException { 136 protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
100 assertNotNull(callback.getPayloadBytes()); 137 assertNotNull(callback.getPayloadBytes());
101 assertNotNull(callback.getObserve()); 138 assertNotNull(callback.getObserve());
102 - assertEquals(1, callback.getObserve().intValue()); 139 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  140 + assertEquals(2, callback.getObserve().intValue());
103 String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); 141 String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
104 assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response)); 142 assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response));
105 } 143 }
@@ -110,13 +148,18 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr @@ -110,13 +148,18 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
110 148
111 private Integer observe; 149 private Integer observe;
112 private byte[] payloadBytes; 150 private byte[] payloadBytes;
  151 + private CoAP.ResponseCode responseCode;
  152 +
  153 + public Integer getObserve() {
  154 + return observe;
  155 + }
113 156
114 public byte[] getPayloadBytes() { 157 public byte[] getPayloadBytes() {
115 return payloadBytes; 158 return payloadBytes;
116 } 159 }
117 160
118 - public Integer getObserve() {  
119 - return observe; 161 + public CoAP.ResponseCode getResponseCode() {
  162 + return responseCode;
120 } 163 }
121 164
122 private TestCoapCallback(CountDownLatch latch) { 165 private TestCoapCallback(CountDownLatch latch) {
@@ -125,10 +168,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr @@ -125,10 +168,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
125 168
126 @Override 169 @Override
127 public void onLoad(CoapResponse response) { 170 public void onLoad(CoapResponse response) {
128 - assertNotNull(response.getPayload());  
129 - assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT);  
130 observe = response.getOptions().getObserve(); 171 observe = response.getOptions().getObserve();
131 payloadBytes = response.getPayload(); 172 payloadBytes = response.getPayload();
  173 + responseCode = response.getCode();
132 latch.countDown(); 174 latch.countDown();
133 } 175 }
134 176
@@ -39,4 +39,9 @@ public abstract class AbstractCoapAttributesUpdatesJsonIntegrationTest extends A @@ -39,4 +39,9 @@ public abstract class AbstractCoapAttributesUpdatesJsonIntegrationTest extends A
39 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception { 39 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
40 super.testSubscribeToAttributesUpdatesFromTheServer(); 40 super.testSubscribeToAttributesUpdatesFromTheServer();
41 } 41 }
  42 +
  43 + @Test
  44 + public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
  45 + super.testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification();
  46 + }
42 } 47 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.transport.coap.attributes.updates; @@ -17,6 +17,7 @@ package org.thingsboard.server.transport.coap.attributes.updates;
17 17
18 import com.google.protobuf.InvalidProtocolBufferException; 18 import com.google.protobuf.InvalidProtocolBufferException;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
  20 +import org.eclipse.californium.core.coap.CoAP;
20 import org.junit.After; 21 import org.junit.After;
21 import org.junit.Before; 22 import org.junit.Before;
22 import org.junit.Test; 23 import org.junit.Test;
@@ -24,11 +25,15 @@ import org.thingsboard.server.common.data.CoapDeviceType; @@ -24,11 +25,15 @@ import org.thingsboard.server.common.data.CoapDeviceType;
24 import org.thingsboard.server.common.data.TransportPayloadType; 25 import org.thingsboard.server.common.data.TransportPayloadType;
25 import org.thingsboard.server.gen.transport.TransportProtos; 26 import org.thingsboard.server.gen.transport.TransportProtos;
26 27
  28 +import java.nio.charset.StandardCharsets;
  29 +import java.util.ArrayList;
  30 +import java.util.Collections;
27 import java.util.List; 31 import java.util.List;
28 import java.util.stream.Collectors; 32 import java.util.stream.Collectors;
29 33
30 import static org.junit.Assert.assertEquals; 34 import static org.junit.Assert.assertEquals;
31 import static org.junit.Assert.assertNotNull; 35 import static org.junit.Assert.assertNotNull;
  36 +import static org.junit.Assert.assertNull;
32 import static org.junit.Assert.assertTrue; 37 import static org.junit.Assert.assertTrue;
33 38
34 @Slf4j 39 @Slf4j
@@ -46,11 +51,54 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends @@ -46,11 +51,54 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends
46 51
47 @Test 52 @Test
48 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception { 53 public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
49 - processTestSubscribeToAttributesUpdates(); 54 + processTestSubscribeToAttributesUpdates(false);
  55 + }
  56 +
  57 + @Test
  58 + public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
  59 + processTestSubscribeToAttributesUpdates(true);
  60 + }
  61 +
  62 + protected void validateCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
  63 + assertNotNull(callback.getPayloadBytes());
  64 + assertNotNull(callback.getObserve());
  65 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  66 + assertEquals(0, callback.getObserve().intValue());
  67 + TransportProtos.AttributeUpdateNotificationMsg.Builder expectedCurrentStateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
  68 + TransportProtos.TsKvProto tsKvProtoAttribute1 = getTsKvProto("attribute1", "value", TransportProtos.KeyValueType.STRING_V);
  69 + TransportProtos.TsKvProto tsKvProtoAttribute2 = getTsKvProto("attribute2", "false", TransportProtos.KeyValueType.BOOLEAN_V);
  70 + TransportProtos.TsKvProto tsKvProtoAttribute3 = getTsKvProto("attribute3", "41.0", TransportProtos.KeyValueType.DOUBLE_V);
  71 + TransportProtos.TsKvProto tsKvProtoAttribute4 = getTsKvProto("attribute4", "72", TransportProtos.KeyValueType.LONG_V);
  72 + TransportProtos.TsKvProto tsKvProtoAttribute5 = getTsKvProto("attribute5", "{\"someNumber\":41,\"someArray\":[],\"someNestedObject\":{\"key\":\"value\"}}", TransportProtos.KeyValueType.JSON_V);
  73 + List<TransportProtos.TsKvProto> tsKvProtoList = new ArrayList<>();
  74 + tsKvProtoList.add(tsKvProtoAttribute1);
  75 + tsKvProtoList.add(tsKvProtoAttribute2);
  76 + tsKvProtoList.add(tsKvProtoAttribute3);
  77 + tsKvProtoList.add(tsKvProtoAttribute4);
  78 + tsKvProtoList.add(tsKvProtoAttribute5);
  79 + TransportProtos.AttributeUpdateNotificationMsg expectedCurrentStateNotificationMsg = expectedCurrentStateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList).build();
  80 + TransportProtos.AttributeUpdateNotificationMsg actualCurrentStateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
  81 +
  82 + List<TransportProtos.KeyValueProto> expectedSharedUpdatedList = expectedCurrentStateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  83 + List<TransportProtos.KeyValueProto> actualSharedUpdatedList = actualCurrentStateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  84 +
  85 + assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());
  86 + assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));
  87 +
  88 + }
  89 +
  90 + protected void validateEmptyCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
  91 + assertNull(callback.getPayloadBytes());
  92 + assertNotNull(callback.getObserve());
  93 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  94 + assertEquals(0, callback.getObserve().intValue());
50 } 95 }
51 96
52 protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException { 97 protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
53 assertNotNull(callback.getPayloadBytes()); 98 assertNotNull(callback.getPayloadBytes());
  99 + assertNotNull(callback.getObserve());
  100 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  101 + assertEquals(1, callback.getObserve().intValue());
54 TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); 102 TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
55 List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList(); 103 List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();
56 attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList); 104 attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);
@@ -68,6 +116,9 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends @@ -68,6 +116,9 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends
68 116
69 protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException { 117 protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
70 assertNotNull(callback.getPayloadBytes()); 118 assertNotNull(callback.getPayloadBytes());
  119 + assertNotNull(callback.getObserve());
  120 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  121 + assertEquals(2, callback.getObserve().intValue());
71 TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); 122 TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
72 attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5"); 123 attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");
73 124
@@ -83,7 +83,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab @@ -83,7 +83,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab
83 83
84 @Test 84 @Test
85 public void testServerCoapTwoWayRpc() throws Exception { 85 public void testServerCoapTwoWayRpc() throws Exception {
86 - processTwoWayRpcTest(); 86 + processTwoWayRpcTest("{\"value1\":\"A\",\"value2\":\"B\"}");
87 } 87 }
88 88
89 } 89 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.transport.coap.rpc; 16 package org.thingsboard.server.transport.coap.rpc;
17 17
  18 +import com.fasterxml.jackson.databind.JsonNode;
18 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
19 import org.apache.commons.lang3.StringUtils; 20 import org.apache.commons.lang3.StringUtils;
20 import org.eclipse.californium.core.CoapClient; 21 import org.eclipse.californium.core.CoapClient;
@@ -24,17 +25,18 @@ import org.eclipse.californium.core.CoapResponse; @@ -24,17 +25,18 @@ import org.eclipse.californium.core.CoapResponse;
24 import org.eclipse.californium.core.coap.CoAP; 25 import org.eclipse.californium.core.coap.CoAP;
25 import org.eclipse.californium.core.coap.MediaTypeRegistry; 26 import org.eclipse.californium.core.coap.MediaTypeRegistry;
26 import org.eclipse.californium.core.coap.Request; 27 import org.eclipse.californium.core.coap.Request;
27 -import org.junit.Assert;  
28 -import org.thingsboard.server.transport.coap.AbstractCoapIntegrationTest; 28 +import org.thingsboard.common.util.JacksonUtil;
29 import org.thingsboard.server.common.data.CoapDeviceType; 29 import org.thingsboard.server.common.data.CoapDeviceType;
30 import org.thingsboard.server.common.data.TransportPayloadType; 30 import org.thingsboard.server.common.data.TransportPayloadType;
31 import org.thingsboard.server.common.msg.session.FeatureType; 31 import org.thingsboard.server.common.msg.session.FeatureType;
  32 +import org.thingsboard.server.transport.coap.AbstractCoapIntegrationTest;
32 33
33 import java.util.concurrent.CountDownLatch; 34 import java.util.concurrent.CountDownLatch;
34 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.TimeUnit;
35 36
36 import static org.junit.Assert.assertEquals; 37 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.assertNotNull; 38 import static org.junit.Assert.assertNotNull;
  39 +import static org.junit.Assert.assertNull;
38 import static org.junit.Assert.assertTrue; 40 import static org.junit.Assert.assertTrue;
39 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 41 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
40 42
@@ -55,57 +57,66 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC @@ -55,57 +57,66 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
55 client.useCONs(); 57 client.useCONs();
56 58
57 CountDownLatch latch = new CountDownLatch(1); 59 CountDownLatch latch = new CountDownLatch(1);
58 - TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, true); 60 + TestCoapCallback callback = new TestCoapCallback(client, latch, true);
59 61
60 Request request = Request.newGet().setObserve(); 62 Request request = Request.newGet().setObserve();
61 - CoapObserveRelation observeRelation = client.observe(request, testCoapCallback); 63 + CoapObserveRelation observeRelation = client.observe(request, callback);
  64 +
  65 + latch.await(3, TimeUnit.SECONDS);
  66 +
  67 + validateCurrentStateNotification(callback);
  68 +
  69 + latch = new CountDownLatch(1);
62 70
63 String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; 71 String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
64 String deviceId = savedDevice.getId().getId().toString(); 72 String deviceId = savedDevice.getId().getId().toString();
65 String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); 73 String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk());
66 - Assert.assertTrue(StringUtils.isEmpty(result)); 74 +
67 latch.await(3, TimeUnit.SECONDS); 75 latch.await(3, TimeUnit.SECONDS);
68 - assertEquals(0, testCoapCallback.getObserve().intValue()); 76 +
  77 + validateOneWayStateChangedNotification(callback, result);
  78 +
69 observeRelation.proactiveCancel(); 79 observeRelation.proactiveCancel();
70 assertTrue(observeRelation.isCanceled()); 80 assertTrue(observeRelation.isCanceled());
71 } 81 }
72 82
73 - protected void processTwoWayRpcTest() throws Exception { 83 + protected void processTwoWayRpcTest(String expectedResponseResult) throws Exception {
74 CoapClient client = getCoapClient(FeatureType.RPC); 84 CoapClient client = getCoapClient(FeatureType.RPC);
75 client.useCONs(); 85 client.useCONs();
76 86
77 CountDownLatch latch = new CountDownLatch(1); 87 CountDownLatch latch = new CountDownLatch(1);
78 - TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, false); 88 + TestCoapCallback callback = new TestCoapCallback(client, latch, false);
79 89
80 Request request = Request.newGet().setObserve(); 90 Request request = Request.newGet().setObserve();
81 request.setType(CoAP.Type.CON); 91 request.setType(CoAP.Type.CON);
82 - CoapObserveRelation observeRelation = client.observe(request, testCoapCallback); 92 + CoapObserveRelation observeRelation = client.observe(request, callback);
  93 +
  94 + latch.await(3, TimeUnit.SECONDS);
  95 +
  96 + validateCurrentStateNotification(callback);
83 97
84 String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; 98 String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";
85 String deviceId = savedDevice.getId().getId().toString(); 99 String deviceId = savedDevice.getId().getId().toString();
86 100
87 - String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; 101 + String actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
  102 + latch.await(3, TimeUnit.SECONDS);
  103 +
  104 + validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult);
88 105
89 - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); 106 + latch = new CountDownLatch(1);
  107 +
  108 + actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
90 latch.await(3, TimeUnit.SECONDS); 109 latch.await(3, TimeUnit.SECONDS);
91 110
92 - assertEquals(expected, result);  
93 - assertEquals(0, testCoapCallback.getObserve().intValue()); 111 + validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult);
  112 +
94 observeRelation.proactiveCancel(); 113 observeRelation.proactiveCancel();
95 assertTrue(observeRelation.isCanceled()); 114 assertTrue(observeRelation.isCanceled());
96 -  
97 -// // TODO: 3/11/21 Fix test to validate next RPC  
98 -// latch = new CountDownLatch(1);  
99 -//  
100 -// result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());  
101 -// latch.await(3, TimeUnit.SECONDS);  
102 -//  
103 -// assertEquals(expected, result);  
104 -// assertEquals(1, testCoapCallback.getObserve().intValue());  
105 } 115 }
106 116
107 protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) { 117 protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) {
108 - client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe)); 118 + JsonNode responseJson = JacksonUtil.fromBytes(response.getPayload());
  119 + client.setURI(getRpcResponseFeatureTokenUrl(accessToken, responseJson.get("id").asInt()));
109 client.post(new CoapHandler() { 120 client.post(new CoapHandler() {
110 @Override 121 @Override
111 public void onLoad(CoapResponse response) { 122 public void onLoad(CoapResponse response) {
@@ -130,11 +141,21 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC @@ -130,11 +141,21 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
130 private final CountDownLatch latch; 141 private final CountDownLatch latch;
131 private final boolean isOneWayRpc; 142 private final boolean isOneWayRpc;
132 143
  144 + private Integer observe;
  145 + private byte[] payloadBytes;
  146 + private CoAP.ResponseCode responseCode;
  147 +
133 public Integer getObserve() { 148 public Integer getObserve() {
134 return observe; 149 return observe;
135 } 150 }
136 151
137 - private Integer observe; 152 + public byte[] getPayloadBytes() {
  153 + return payloadBytes;
  154 + }
  155 +
  156 + public CoAP.ResponseCode getResponseCode() {
  157 + return responseCode;
  158 + }
138 159
139 TestCoapCallback(CoapClient client, CountDownLatch latch, boolean isOneWayRpc) { 160 TestCoapCallback(CoapClient client, CountDownLatch latch, boolean isOneWayRpc) {
140 this.client = client; 161 this.client = client;
@@ -144,14 +165,15 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC @@ -144,14 +165,15 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
144 165
145 @Override 166 @Override
146 public void onLoad(CoapResponse response) { 167 public void onLoad(CoapResponse response) {
147 - log.warn("coap response: {}, {}", response.getResponseText(), response.getCode());  
148 - assertNotNull(response.getPayload());  
149 - assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT); 168 + payloadBytes = response.getPayload();
  169 + responseCode = response.getCode();
150 observe = response.getOptions().getObserve(); 170 observe = response.getOptions().getObserve();
151 - if (!isOneWayRpc) {  
152 - processOnLoadResponse(response, client, observe, latch);  
153 - } else {  
154 - latch.countDown(); 171 + if (observe != null) {
  172 + if (!isOneWayRpc && observe > 0) {
  173 + processOnLoadResponse(response, client, observe, latch);
  174 + } else {
  175 + latch.countDown();
  176 + }
155 } 177 }
156 } 178 }
157 179
@@ -162,4 +184,28 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC @@ -162,4 +184,28 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
162 184
163 } 185 }
164 186
  187 + private void validateCurrentStateNotification(TestCoapCallback callback) {
  188 + assertNull(callback.getPayloadBytes());
  189 + assertNotNull(callback.getObserve());
  190 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode.VALID);
  191 + assertEquals(0, callback.getObserve().intValue());
  192 + }
  193 +
  194 + private void validateOneWayStateChangedNotification(TestCoapCallback callback, String result) {
  195 + assertTrue(StringUtils.isEmpty(result));
  196 + assertNotNull(callback.getPayloadBytes());
  197 + assertNotNull(callback.getObserve());
  198 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  199 + assertEquals(1, callback.getObserve().intValue());
  200 + }
  201 +
  202 + private void validateTwoWayStateChangedNotification(TestCoapCallback callback, int expectedObserveNumber, String expectedResult, String actualResult) {
  203 + assertEquals(expectedResult, actualResult);
  204 + assertNotNull(callback.getPayloadBytes());
  205 + assertNotNull(callback.getObserve());
  206 + assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  207 + assertEquals(expectedObserveNumber, callback.getObserve().intValue());
  208 + }
  209 +
  210 +
165 } 211 }
@@ -42,7 +42,7 @@ public abstract class AbstractCoapServerSideRpcJsonIntegrationTest extends Abstr @@ -42,7 +42,7 @@ public abstract class AbstractCoapServerSideRpcJsonIntegrationTest extends Abstr
42 42
43 @Test 43 @Test
44 public void testServerCoapTwoWayRpc() throws Exception { 44 public void testServerCoapTwoWayRpc() throws Exception {
45 - processTwoWayRpcTest(); 45 + processTwoWayRpcTest("{\"value1\":\"A\",\"value2\":\"B\"}");
46 } 46 }
47 47
48 } 48 }
@@ -85,37 +85,11 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst @@ -85,37 +85,11 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst
85 85
86 @Test 86 @Test
87 public void testServerCoapTwoWayRpc() throws Exception { 87 public void testServerCoapTwoWayRpc() throws Exception {
88 - processTwoWayRpcTest();  
89 - }  
90 -  
91 - protected void processTwoWayRpcTest() throws Exception {  
92 - CoapClient client = getCoapClient(FeatureType.RPC);  
93 - client.useCONs();  
94 -  
95 - CountDownLatch latch = new CountDownLatch(1);  
96 - TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, false);  
97 -  
98 - Request request = Request.newGet().setObserve();  
99 - request.setType(CoAP.Type.CON);  
100 - CoapObserveRelation observeRelation = client.observe(request, testCoapCallback);  
101 -  
102 - String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";  
103 - String deviceId = savedDevice.getId().getId().toString();  
104 -  
105 - String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}";  
106 -  
107 - String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());  
108 - latch.await(3, TimeUnit.SECONDS);  
109 -  
110 - assertEquals(expected, result);  
111 - assertEquals(0, testCoapCallback.getObserve().intValue());  
112 - observeRelation.proactiveCancel();  
113 - assertTrue(observeRelation.isCanceled()); 88 + processTwoWayRpcTest("{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}");
114 } 89 }
115 90
116 @Override 91 @Override
117 protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) { 92 protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) {
118 - client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe));  
119 ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration(); 93 ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration();
120 ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA); 94 ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA);
121 DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA); 95 DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA);
@@ -123,25 +97,22 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst @@ -123,25 +97,22 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst
123 byte[] requestPayload = response.getPayload(); 97 byte[] requestPayload = response.getPayload();
124 DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg"); 98 DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg");
125 Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType(); 99 Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType();
126 - assertNotNull(rpcRequestMsgDescriptor);  
127 try { 100 try {
128 DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload); 101 DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload);
129 - List<Descriptors.FieldDescriptor> fields = rpcRequestMsgDescriptor.getFields();  
130 - for (Descriptors.FieldDescriptor fieldDescriptor: fields) {  
131 - assertTrue(dynamicMessage.hasField(fieldDescriptor));  
132 - } 102 + Descriptors.FieldDescriptor requestIdDescriptor = rpcRequestMsgDescriptor.findFieldByName("requestId");
  103 + int requestId = (int) dynamicMessage.getField(requestIdDescriptor);
133 ProtoFileElement rpcResponseProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA); 104 ProtoFileElement rpcResponseProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA);
134 DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcResponseProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA); 105 DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcResponseProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA);
135 DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg"); 106 DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg");
136 Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType(); 107 Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType();
137 - assertNotNull(rpcResponseMsgDescriptor);  
138 DynamicMessage rpcResponseMsg = rpcResponseBuilder 108 DynamicMessage rpcResponseMsg = rpcResponseBuilder
139 .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE) 109 .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE)
140 .build(); 110 .build();
  111 + client.setURI(getRpcResponseFeatureTokenUrl(accessToken, requestId));
141 client.post(new CoapHandler() { 112 client.post(new CoapHandler() {
142 @Override 113 @Override
143 public void onLoad(CoapResponse response) { 114 public void onLoad(CoapResponse response) {
144 - log.warn("Command Response Ack: {}, {}", response.getCode(), response.getResponseText()); 115 + log.warn("Command Response Ack: {}", response.getCode());
145 latch.countDown(); 116 latch.countDown();
146 } 117 }
147 118
common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java renamed from common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java
@@ -13,19 +13,20 @@ @@ -13,19 +13,20 @@
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.cache.firmware; 16 +package org.thingsboard.server.cache.ota;
17 17
18 import lombok.RequiredArgsConstructor; 18 import lombok.RequiredArgsConstructor;
19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20 import org.springframework.cache.CacheManager; 20 import org.springframework.cache.CacheManager;
21 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
22 22
23 -import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE; 23 +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE;
  24 +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE;
24 25
25 @Service 26 @Service
26 @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true) 27 @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true)
27 @RequiredArgsConstructor 28 @RequiredArgsConstructor
28 -public class CaffeineFirmwareCache implements FirmwareDataCache { 29 +public class CaffeineOtaPackageCache implements OtaPackageDataCache {
29 30
30 private final CacheManager cacheManager; 31 private final CacheManager cacheManager;
31 32
@@ -36,7 +37,7 @@ public class CaffeineFirmwareCache implements FirmwareDataCache { @@ -36,7 +37,7 @@ public class CaffeineFirmwareCache implements FirmwareDataCache {
36 37
37 @Override 38 @Override
38 public byte[] get(String key, int chunkSize, int chunk) { 39 public byte[] get(String key, int chunkSize, int chunk) {
39 - byte[] data = cacheManager.getCache(FIRMWARE_CACHE).get(key, byte[].class); 40 + byte[] data = cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).get(key, byte[].class);
40 41
41 if (chunkSize < 1) { 42 if (chunkSize < 1) {
42 return data; 43 return data;
@@ -58,11 +59,11 @@ public class CaffeineFirmwareCache implements FirmwareDataCache { @@ -58,11 +59,11 @@ public class CaffeineFirmwareCache implements FirmwareDataCache {
58 59
59 @Override 60 @Override
60 public void put(String key, byte[] value) { 61 public void put(String key, byte[] value) {
61 - cacheManager.getCache(FIRMWARE_CACHE).putIfAbsent(key, value); 62 + cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).putIfAbsent(key, value);
62 } 63 }
63 64
64 @Override 65 @Override
65 public void evict(String key) { 66 public void evict(String key) {
66 - cacheManager.getCache(FIRMWARE_CACHE).evict(key); 67 + cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).evict(key);
67 } 68 }
68 } 69 }
common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java renamed from common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java
@@ -13,9 +13,9 @@ @@ -13,9 +13,9 @@
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.cache.firmware; 16 +package org.thingsboard.server.cache.ota;
17 17
18 -public interface FirmwareDataCache { 18 +public interface OtaPackageDataCache {
19 19
20 byte[] get(String key); 20 byte[] get(String key);
21 21
@@ -25,8 +25,8 @@ public interface FirmwareDataCache { @@ -25,8 +25,8 @@ public interface FirmwareDataCache {
25 25
26 void evict(String key); 26 void evict(String key);
27 27
28 - default boolean has(String firmwareId) {  
29 - byte[] data = get(firmwareId, 1, 0); 28 + default boolean has(String otaPackageId) {
  29 + byte[] data = get(otaPackageId, 1, 0);
30 return data != null && data.length > 0; 30 return data != null && data.length > 0;
31 } 31 }
32 } 32 }
common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java renamed from common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
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.cache.firmware; 16 +package org.thingsboard.server.cache.ota;
17 17
18 import lombok.RequiredArgsConstructor; 18 import lombok.RequiredArgsConstructor;
19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -21,12 +21,13 @@ import org.springframework.data.redis.connection.RedisConnection; @@ -21,12 +21,13 @@ import org.springframework.data.redis.connection.RedisConnection;
21 import org.springframework.data.redis.connection.RedisConnectionFactory; 21 import org.springframework.data.redis.connection.RedisConnectionFactory;
22 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
23 23
24 -import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE; 24 +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE;
  25 +import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE;
25 26
26 @Service 27 @Service
27 @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") 28 @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
28 @RequiredArgsConstructor 29 @RequiredArgsConstructor
29 -public class RedisFirmwareDataCache implements FirmwareDataCache { 30 +public class RedisOtaPackageDataCache implements OtaPackageDataCache {
30 31
31 private final RedisConnectionFactory redisConnectionFactory; 32 private final RedisConnectionFactory redisConnectionFactory;
32 33
@@ -39,30 +40,30 @@ public class RedisFirmwareDataCache implements FirmwareDataCache { @@ -39,30 +40,30 @@ public class RedisFirmwareDataCache implements FirmwareDataCache {
39 public byte[] get(String key, int chunkSize, int chunk) { 40 public byte[] get(String key, int chunkSize, int chunk) {
40 try (RedisConnection connection = redisConnectionFactory.getConnection()) { 41 try (RedisConnection connection = redisConnectionFactory.getConnection()) {
41 if (chunkSize == 0) { 42 if (chunkSize == 0) {
42 - return connection.get(toFirmwareCacheKey(key)); 43 + return connection.get(toOtaPackageCacheKey(key));
43 } 44 }
44 45
45 int startIndex = chunkSize * chunk; 46 int startIndex = chunkSize * chunk;
46 int endIndex = startIndex + chunkSize - 1; 47 int endIndex = startIndex + chunkSize - 1;
47 - return connection.getRange(toFirmwareCacheKey(key), startIndex, endIndex); 48 + return connection.getRange(toOtaPackageCacheKey(key), startIndex, endIndex);
48 } 49 }
49 } 50 }
50 51
51 @Override 52 @Override
52 public void put(String key, byte[] value) { 53 public void put(String key, byte[] value) {
53 try (RedisConnection connection = redisConnectionFactory.getConnection()) { 54 try (RedisConnection connection = redisConnectionFactory.getConnection()) {
54 - connection.set(toFirmwareCacheKey(key), value); 55 + connection.set(toOtaPackageCacheKey(key), value);
55 } 56 }
56 } 57 }
57 58
58 @Override 59 @Override
59 public void evict(String key) { 60 public void evict(String key) {
60 try (RedisConnection connection = redisConnectionFactory.getConnection()) { 61 try (RedisConnection connection = redisConnectionFactory.getConnection()) {
61 - connection.del(toFirmwareCacheKey(key)); 62 + connection.del(toOtaPackageCacheKey(key));
62 } 63 }
63 } 64 }
64 65
65 - private byte[] toFirmwareCacheKey(String key) {  
66 - return String.format("%s::%s", FIRMWARE_CACHE, key).getBytes(); 66 + private byte[] toOtaPackageCacheKey(String key) {
  67 + return String.format("%s::%s", OTA_PACKAGE_DATA_CACHE, key).getBytes();
67 } 68 }
68 } 69 }
@@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.DeviceId; @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
27 import org.thingsboard.server.common.data.id.DeviceProfileId; 27 import org.thingsboard.server.common.data.id.DeviceProfileId;
28 import org.thingsboard.server.common.data.id.EdgeId; 28 import org.thingsboard.server.common.data.id.EdgeId;
29 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
  30 +import org.thingsboard.server.common.data.ota.OtaPackageType;
30 import org.thingsboard.server.common.data.page.PageData; 31 import org.thingsboard.server.common.data.page.PageData;
31 import org.thingsboard.server.common.data.page.PageLink; 32 import org.thingsboard.server.common.data.page.PageLink;
32 import org.thingsboard.server.common.data.security.DeviceCredentials; 33 import org.thingsboard.server.common.data.security.DeviceCredentials;
@@ -63,9 +64,9 @@ public interface DeviceService { @@ -63,9 +64,9 @@ public interface DeviceService {
63 64
64 PageData<Device> findDevicesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); 65 PageData<Device> findDevicesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
65 66
66 - PageData<Device> findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink); 67 + PageData<Device> findDevicesByTenantIdAndTypeAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type, PageLink pageLink);
67 68
68 - PageData<Device> findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink); 69 + Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType);
69 70
70 PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink); 71 PageData<DeviceInfo> findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
71 72
common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java renamed from common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java
@@ -13,40 +13,40 @@ @@ -13,40 +13,40 @@
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.dao.firmware; 16 +package org.thingsboard.server.dao.ota;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 -import org.thingsboard.server.common.data.Firmware;  
20 -import org.thingsboard.server.common.data.FirmwareInfo;  
21 -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;  
22 -import org.thingsboard.server.common.data.firmware.FirmwareType; 19 +import org.thingsboard.server.common.data.OtaPackage;
  20 +import org.thingsboard.server.common.data.OtaPackageInfo;
  21 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  22 +import org.thingsboard.server.common.data.ota.OtaPackageType;
23 import org.thingsboard.server.common.data.id.DeviceProfileId; 23 import org.thingsboard.server.common.data.id.DeviceProfileId;
24 -import org.thingsboard.server.common.data.id.FirmwareId; 24 +import org.thingsboard.server.common.data.id.OtaPackageId;
25 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.page.PageData; 26 import org.thingsboard.server.common.data.page.PageData;
27 import org.thingsboard.server.common.data.page.PageLink; 27 import org.thingsboard.server.common.data.page.PageLink;
28 28
29 import java.nio.ByteBuffer; 29 import java.nio.ByteBuffer;
30 30
31 -public interface FirmwareService { 31 +public interface OtaPackageService {
32 32
33 - FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo); 33 + OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo);
34 34
35 - Firmware saveFirmware(Firmware firmware); 35 + OtaPackage saveOtaPackage(OtaPackage otaPackage);
36 36
37 String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data); 37 String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data);
38 38
39 - Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId); 39 + OtaPackage findOtaPackageById(TenantId tenantId, OtaPackageId otaPackageId);
40 40
41 - FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId); 41 + OtaPackageInfo findOtaPackageInfoById(TenantId tenantId, OtaPackageId otaPackageId);
42 42
43 - ListenableFuture<FirmwareInfo> findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId); 43 + ListenableFuture<OtaPackageInfo> findOtaPackageInfoByIdAsync(TenantId tenantId, OtaPackageId otaPackageId);
44 44
45 - PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); 45 + PageData<OtaPackageInfo> findTenantOtaPackagesByTenantId(TenantId tenantId, PageLink pageLink);
46 46
47 - PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink); 47 + PageData<OtaPackageInfo> findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink);
48 48
49 - void deleteFirmware(TenantId tenantId, FirmwareId firmwareId); 49 + void deleteOtaPackage(TenantId tenantId, OtaPackageId otaPackageId);
50 50
51 - void deleteFirmwaresByTenantId(TenantId tenantId); 51 + void deleteOtaPackagesByTenantId(TenantId tenantId);
52 } 52 }
@@ -29,5 +29,6 @@ public class CacheConstants { @@ -29,5 +29,6 @@ public class CacheConstants {
29 public static final String DEVICE_PROFILE_CACHE = "deviceProfiles"; 29 public static final String DEVICE_PROFILE_CACHE = "deviceProfiles";
30 public static final String ATTRIBUTES_CACHE = "attributes"; 30 public static final String ATTRIBUTES_CACHE = "attributes";
31 public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime"; 31 public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime";
32 - public static final String FIRMWARE_CACHE = "firmwares"; 32 + public static final String OTA_PACKAGE_CACHE = "otaPackages";
  33 + public static final String OTA_PACKAGE_DATA_CACHE = "otaPackagesData";
33 } 34 }
@@ -66,6 +66,7 @@ public class DataConstants { @@ -66,6 +66,7 @@ public class DataConstants {
66 public static final String TIMESERIES_DELETED = "TIMESERIES_DELETED"; 66 public static final String TIMESERIES_DELETED = "TIMESERIES_DELETED";
67 public static final String ALARM_ACK = "ALARM_ACK"; 67 public static final String ALARM_ACK = "ALARM_ACK";
68 public static final String ALARM_CLEAR = "ALARM_CLEAR"; 68 public static final String ALARM_CLEAR = "ALARM_CLEAR";
  69 + public static final String ALARM_DELETE = "ALARM_DELETE";
69 public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT"; 70 public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT";
70 public static final String ENTITY_ASSIGNED_TO_TENANT = "ENTITY_ASSIGNED_TO_TENANT"; 71 public static final String ENTITY_ASSIGNED_TO_TENANT = "ENTITY_ASSIGNED_TO_TENANT";
71 public static final String PROVISION_SUCCESS = "PROVISION_SUCCESS"; 72 public static final String PROVISION_SUCCESS = "PROVISION_SUCCESS";
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
23 import org.thingsboard.server.common.data.id.CustomerId; 23 import org.thingsboard.server.common.data.id.CustomerId;
24 import org.thingsboard.server.common.data.id.DeviceId; 24 import org.thingsboard.server.common.data.id.DeviceId;
25 import org.thingsboard.server.common.data.id.DeviceProfileId; 25 import org.thingsboard.server.common.data.id.DeviceProfileId;
26 -import org.thingsboard.server.common.data.id.FirmwareId; 26 +import org.thingsboard.server.common.data.id.OtaPackageId;
27 import org.thingsboard.server.common.data.id.TenantId; 27 import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.validation.NoXss; 28 import org.thingsboard.server.common.data.validation.NoXss;
29 29
@@ -32,7 +32,7 @@ import java.io.IOException; @@ -32,7 +32,7 @@ import java.io.IOException;
32 32
33 @EqualsAndHashCode(callSuper = true) 33 @EqualsAndHashCode(callSuper = true)
34 @Slf4j 34 @Slf4j
35 -public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasFirmware { 35 +public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasOtaPackage {
36 36
37 private static final long serialVersionUID = 2807343040519543363L; 37 private static final long serialVersionUID = 2807343040519543363L;
38 38
@@ -49,8 +49,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -49,8 +49,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
49 @JsonIgnore 49 @JsonIgnore
50 private byte[] deviceDataBytes; 50 private byte[] deviceDataBytes;
51 51
52 - private FirmwareId firmwareId;  
53 - private FirmwareId softwareId; 52 + private OtaPackageId firmwareId;
  53 + private OtaPackageId softwareId;
54 54
55 public Device() { 55 public Device() {
56 super(); 56 super();
@@ -167,19 +167,19 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -167,19 +167,19 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
167 return getName(); 167 return getName();
168 } 168 }
169 169
170 - public FirmwareId getFirmwareId() { 170 + public OtaPackageId getFirmwareId() {
171 return firmwareId; 171 return firmwareId;
172 } 172 }
173 173
174 - public void setFirmwareId(FirmwareId firmwareId) { 174 + public void setFirmwareId(OtaPackageId firmwareId) {
175 this.firmwareId = firmwareId; 175 this.firmwareId = firmwareId;
176 } 176 }
177 177
178 - public FirmwareId getSoftwareId() { 178 + public OtaPackageId getSoftwareId() {
179 return softwareId; 179 return softwareId;
180 } 180 }
181 181
182 - public void setSoftwareId(FirmwareId softwareId) { 182 + public void setSoftwareId(OtaPackageId softwareId) {
183 this.softwareId = softwareId; 183 this.softwareId = softwareId;
184 } 184 }
185 185
@@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j; @@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j;
23 import org.thingsboard.server.common.data.device.profile.DeviceProfileData; 23 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
24 import org.thingsboard.server.common.data.id.DashboardId; 24 import org.thingsboard.server.common.data.id.DashboardId;
25 import org.thingsboard.server.common.data.id.DeviceProfileId; 25 import org.thingsboard.server.common.data.id.DeviceProfileId;
26 -import org.thingsboard.server.common.data.id.FirmwareId; 26 +import org.thingsboard.server.common.data.id.OtaPackageId;
27 import org.thingsboard.server.common.data.id.RuleChainId; 27 import org.thingsboard.server.common.data.id.RuleChainId;
28 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
29 import org.thingsboard.server.common.data.validation.NoXss; 29 import org.thingsboard.server.common.data.validation.NoXss;
@@ -37,7 +37,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn @@ -37,7 +37,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn
37 @Data 37 @Data
38 @EqualsAndHashCode(callSuper = true) 38 @EqualsAndHashCode(callSuper = true)
39 @Slf4j 39 @Slf4j
40 -public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId, HasFirmware { 40 +public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName, HasTenantId, HasOtaPackage {
41 41
42 private TenantId tenantId; 42 private TenantId tenantId;
43 @NoXss 43 @NoXss
@@ -60,9 +60,9 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H @@ -60,9 +60,9 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
60 @NoXss 60 @NoXss
61 private String provisionDeviceKey; 61 private String provisionDeviceKey;
62 62
63 - private FirmwareId firmwareId; 63 + private OtaPackageId firmwareId;
64 64
65 - private FirmwareId softwareId; 65 + private OtaPackageId softwareId;
66 66
67 public DeviceProfile() { 67 public DeviceProfile() {
68 super(); 68 super();
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
19 * @author Andrew Shvayka 19 * @author Andrew Shvayka
20 */ 20 */
21 public enum EntityType { 21 public enum EntityType {
22 - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, FIRMWARE, EDGE; 22 + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE;
23 } 23 }
common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java
@@ -15,11 +15,11 @@ @@ -15,11 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 -import org.thingsboard.server.common.data.id.FirmwareId; 18 +import org.thingsboard.server.common.data.id.OtaPackageId;
19 19
20 -public interface HasFirmware { 20 +public interface HasOtaPackage {
21 21
22 - FirmwareId getFirmwareId(); 22 + OtaPackageId getFirmwareId();
23 23
24 - FirmwareId getSoftwareId(); 24 + OtaPackageId getSoftwareId();
25 } 25 }
common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java
@@ -17,27 +17,27 @@ package org.thingsboard.server.common.data; @@ -17,27 +17,27 @@ package org.thingsboard.server.common.data;
17 17
18 import lombok.Data; 18 import lombok.Data;
19 import lombok.EqualsAndHashCode; 19 import lombok.EqualsAndHashCode;
20 -import org.thingsboard.server.common.data.id.FirmwareId; 20 +import org.thingsboard.server.common.data.id.OtaPackageId;
21 21
22 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
23 23
24 @Data 24 @Data
25 @EqualsAndHashCode(callSuper = true) 25 @EqualsAndHashCode(callSuper = true)
26 -public class Firmware extends FirmwareInfo { 26 +public class OtaPackage extends OtaPackageInfo {
27 27
28 private static final long serialVersionUID = 3091601761339422546L; 28 private static final long serialVersionUID = 3091601761339422546L;
29 29
30 private transient ByteBuffer data; 30 private transient ByteBuffer data;
31 31
32 - public Firmware() { 32 + public OtaPackage() {
33 super(); 33 super();
34 } 34 }
35 35
36 - public Firmware(FirmwareId id) { 36 + public OtaPackage(OtaPackageId id) {
37 super(id); 37 super(id);
38 } 38 }
39 39
40 - public Firmware(Firmware firmware) { 40 + public OtaPackage(OtaPackage firmware) {
41 super(firmware); 41 super(firmware);
42 this.data = firmware.getData(); 42 this.data = firmware.getData();
43 } 43 }
common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java
@@ -19,22 +19,22 @@ import com.fasterxml.jackson.annotation.JsonIgnore; @@ -19,22 +19,22 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
19 import lombok.Data; 19 import lombok.Data;
20 import lombok.EqualsAndHashCode; 20 import lombok.EqualsAndHashCode;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 -import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;  
23 -import org.thingsboard.server.common.data.firmware.FirmwareType; 22 +import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
  23 +import org.thingsboard.server.common.data.ota.OtaPackageType;
24 import org.thingsboard.server.common.data.id.DeviceProfileId; 24 import org.thingsboard.server.common.data.id.DeviceProfileId;
25 -import org.thingsboard.server.common.data.id.FirmwareId; 25 +import org.thingsboard.server.common.data.id.OtaPackageId;
26 import org.thingsboard.server.common.data.id.TenantId; 26 import org.thingsboard.server.common.data.id.TenantId;
27 27
28 @Slf4j 28 @Slf4j
29 @Data 29 @Data
30 @EqualsAndHashCode(callSuper = true) 30 @EqualsAndHashCode(callSuper = true)
31 -public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> implements HasName, HasTenantId { 31 +public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackageId> implements HasName, HasTenantId {
32 32
33 private static final long serialVersionUID = 3168391583570815419L; 33 private static final long serialVersionUID = 3168391583570815419L;
34 34
35 private TenantId tenantId; 35 private TenantId tenantId;
36 private DeviceProfileId deviceProfileId; 36 private DeviceProfileId deviceProfileId;
37 - private FirmwareType type; 37 + private OtaPackageType type;
38 private String title; 38 private String title;
39 private String version; 39 private String version;
40 private boolean hasData; 40 private boolean hasData;
@@ -45,27 +45,27 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> @@ -45,27 +45,27 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
45 private Long dataSize; 45 private Long dataSize;
46 46
47 47
48 - public FirmwareInfo() { 48 + public OtaPackageInfo() {
49 super(); 49 super();
50 } 50 }
51 51
52 - public FirmwareInfo(FirmwareId id) { 52 + public OtaPackageInfo(OtaPackageId id) {
53 super(id); 53 super(id);
54 } 54 }
55 55
56 - public FirmwareInfo(FirmwareInfo firmwareInfo) {  
57 - super(firmwareInfo);  
58 - this.tenantId = firmwareInfo.getTenantId();  
59 - this.deviceProfileId = firmwareInfo.getDeviceProfileId();  
60 - this.type = firmwareInfo.getType();  
61 - this.title = firmwareInfo.getTitle();  
62 - this.version = firmwareInfo.getVersion();  
63 - this.hasData = firmwareInfo.isHasData();  
64 - this.fileName = firmwareInfo.getFileName();  
65 - this.contentType = firmwareInfo.getContentType();  
66 - this.checksumAlgorithm = firmwareInfo.getChecksumAlgorithm();  
67 - this.checksum = firmwareInfo.getChecksum();  
68 - this.dataSize = firmwareInfo.getDataSize(); 56 + public OtaPackageInfo(OtaPackageInfo otaPackageInfo) {
  57 + super(otaPackageInfo);
  58 + this.tenantId = otaPackageInfo.getTenantId();
  59 + this.deviceProfileId = otaPackageInfo.getDeviceProfileId();
  60 + this.type = otaPackageInfo.getType();
  61 + this.title = otaPackageInfo.getTitle();
  62 + this.version = otaPackageInfo.getVersion();
  63 + this.hasData = otaPackageInfo.isHasData();
  64 + this.fileName = otaPackageInfo.getFileName();
  65 + this.contentType = otaPackageInfo.getContentType();
  66 + this.checksumAlgorithm = otaPackageInfo.getChecksumAlgorithm();
  67 + this.checksum = otaPackageInfo.getChecksum();
  68 + this.dataSize = otaPackageInfo.getDataSize();
69 } 69 }
70 70
71 @Override 71 @Override
@@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.validation.NoXss; @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
27 27
28 import java.io.ByteArrayInputStream; 28 import java.io.ByteArrayInputStream;
29 import java.io.IOException; 29 import java.io.IOException;
  30 +import java.util.Optional;
30 31
31 import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.mapper; 32 import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.mapper;
32 33
@@ -92,6 +93,13 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H @@ -92,6 +93,13 @@ public class TenantProfile extends SearchTextBased<TenantProfileId> implements H
92 } 93 }
93 } 94 }
94 95
  96 + @JsonIgnore
  97 + public Optional<DefaultTenantProfileConfiguration> getProfileConfiguration() {
  98 + return Optional.ofNullable(getProfileData().getConfiguration())
  99 + .filter(profileConfiguration -> profileConfiguration instanceof DefaultTenantProfileConfiguration)
  100 + .map(profileConfiguration -> (DefaultTenantProfileConfiguration) profileConfiguration);
  101 + }
  102 +
95 public TenantProfileData createDefaultTenantProfileData() { 103 public TenantProfileData createDefaultTenantProfileData() {
96 TenantProfileData tpd = new TenantProfileData(); 104 TenantProfileData tpd = new TenantProfileData();
97 tpd.setConfiguration(new DefaultTenantProfileConfiguration()); 105 tpd.setConfiguration(new DefaultTenantProfileConfiguration());
@@ -39,6 +39,7 @@ public enum ActionType { @@ -39,6 +39,7 @@ public enum ActionType {
39 RELATIONS_DELETED(false), 39 RELATIONS_DELETED(false),
40 ALARM_ACK(false), 40 ALARM_ACK(false),
41 ALARM_CLEAR(false), 41 ALARM_CLEAR(false),
  42 + ALARM_DELETE(false),
42 LOGIN(false), 43 LOGIN(false),
43 LOGOUT(false), 44 LOGOUT(false),
44 LOCKOUT(false), 45 LOCKOUT(false),
  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.common.data.exception;
  17 +
  18 +public class ApiUsageLimitsExceededException extends RuntimeException {
  19 + public ApiUsageLimitsExceededException(String message) {
  20 + super(message);
  21 + }
  22 +
  23 + public ApiUsageLimitsExceededException() {
  24 + }
  25 +}
@@ -71,8 +71,8 @@ public class EntityIdFactory { @@ -71,8 +71,8 @@ public class EntityIdFactory {
71 return new ApiUsageStateId(uuid); 71 return new ApiUsageStateId(uuid);
72 case TB_RESOURCE: 72 case TB_RESOURCE:
73 return new TbResourceId(uuid); 73 return new TbResourceId(uuid);
74 - case FIRMWARE:  
75 - return new FirmwareId(uuid); 74 + case OTA_PACKAGE:
  75 + return new OtaPackageId(uuid);
76 case EDGE: 76 case EDGE:
77 return new EdgeId(uuid); 77 return new EdgeId(uuid);
78 } 78 }
common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java
@@ -22,23 +22,23 @@ import org.thingsboard.server.common.data.EntityType; @@ -22,23 +22,23 @@ import org.thingsboard.server.common.data.EntityType;
22 22
23 import java.util.UUID; 23 import java.util.UUID;
24 24
25 -public class FirmwareId extends UUIDBased implements EntityId { 25 +public class OtaPackageId extends UUIDBased implements EntityId {
26 26
27 private static final long serialVersionUID = 1L; 27 private static final long serialVersionUID = 1L;
28 28
29 @JsonCreator 29 @JsonCreator
30 - public FirmwareId(@JsonProperty("id") UUID id) { 30 + public OtaPackageId(@JsonProperty("id") UUID id) {
31 super(id); 31 super(id);
32 } 32 }
33 33
34 - public static FirmwareId fromString(String firmwareId) {  
35 - return new FirmwareId(UUID.fromString(firmwareId)); 34 + public static OtaPackageId fromString(String firmwareId) {
  35 + return new OtaPackageId(UUID.fromString(firmwareId));
36 } 36 }
37 37
38 @JsonIgnore 38 @JsonIgnore
39 @Override 39 @Override
40 public EntityType getEntityType() { 40 public EntityType getEntityType() {
41 - return EntityType.FIRMWARE; 41 + return EntityType.OTA_PACKAGE;
42 } 42 }
43 43
44 } 44 }
common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
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.common.data.firmware; 16 +package org.thingsboard.server.common.data.ota;
17 17
18 public enum ChecksumAlgorithm { 18 public enum ChecksumAlgorithm {
19 MD5, 19 MD5,
common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java
@@ -13,18 +13,18 @@ @@ -13,18 +13,18 @@
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.common.data.firmware; 16 +package org.thingsboard.server.common.data.ota;
17 17
18 import lombok.Getter; 18 import lombok.Getter;
19 19
20 -public enum FirmwareKey { 20 +public enum OtaPackageKey {
21 21
22 TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm"); 22 TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm");
23 23
24 @Getter 24 @Getter
25 private final String value; 25 private final String value;
26 26
27 - FirmwareKey(String value) { 27 + OtaPackageKey(String value) {
28 this.value = value; 28 this.value = value;
29 } 29 }
30 } 30 }
common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java
@@ -13,18 +13,18 @@ @@ -13,18 +13,18 @@
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.common.data.firmware; 16 +package org.thingsboard.server.common.data.ota;
17 17
18 import lombok.Getter; 18 import lombok.Getter;
19 19
20 -public enum FirmwareType { 20 +public enum OtaPackageType {
21 21
22 FIRMWARE("fw"), SOFTWARE("sw"); 22 FIRMWARE("fw"), SOFTWARE("sw");
23 23
24 @Getter 24 @Getter
25 private final String keyPrefix; 25 private final String keyPrefix;
26 26
27 - FirmwareType(String keyPrefix) { 27 + OtaPackageType(String keyPrefix) {
28 this.keyPrefix = keyPrefix; 28 this.keyPrefix = keyPrefix;
29 } 29 }
30 } 30 }
common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java
@@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
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.common.data.firmware; 16 +package org.thingsboard.server.common.data.ota;
17 17
18 -public enum FirmwareUpdateStatus { 18 +public enum OtaPackageUpdateStatus {
19 QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED 19 QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
20 } 20 }
common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java
@@ -13,21 +13,19 @@ @@ -13,21 +13,19 @@
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.common.data.firmware; 16 +package org.thingsboard.server.common.data.ota;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 -import org.thingsboard.server.common.data.HasFirmware;  
20 -import org.thingsboard.server.common.data.id.FirmwareId; 19 +import org.thingsboard.server.common.data.HasOtaPackage;
  20 +import org.thingsboard.server.common.data.id.OtaPackageId;
21 21
22 import java.util.ArrayList; 22 import java.util.ArrayList;
23 import java.util.Collections; 23 import java.util.Collections;
24 import java.util.List; 24 import java.util.List;
25 -  
26 -import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;  
27 -import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; 25 +import java.util.function.Supplier;
28 26
29 @Slf4j 27 @Slf4j
30 -public class FirmwareUtil { 28 +public class OtaPackageUtil {
31 29
32 public static final List<String> ALL_FW_ATTRIBUTE_KEYS; 30 public static final List<String> ALL_FW_ATTRIBUTE_KEYS;
33 31
@@ -35,19 +33,19 @@ public class FirmwareUtil { @@ -35,19 +33,19 @@ public class FirmwareUtil {
35 33
36 static { 34 static {
37 ALL_FW_ATTRIBUTE_KEYS = new ArrayList<>(); 35 ALL_FW_ATTRIBUTE_KEYS = new ArrayList<>();
38 - for (FirmwareKey key : FirmwareKey.values()) {  
39 - ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(FIRMWARE, key)); 36 + for (OtaPackageKey key : OtaPackageKey.values()) {
  37 + ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.FIRMWARE, key));
40 38
41 } 39 }
42 40
43 ALL_SW_ATTRIBUTE_KEYS = new ArrayList<>(); 41 ALL_SW_ATTRIBUTE_KEYS = new ArrayList<>();
44 - for (FirmwareKey key : FirmwareKey.values()) {  
45 - ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(SOFTWARE, key)); 42 + for (OtaPackageKey key : OtaPackageKey.values()) {
  43 + ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.SOFTWARE, key));
46 44
47 } 45 }
48 } 46 }
49 47
50 - public static List<String> getAttributeKeys(FirmwareType firmwareType) { 48 + public static List<String> getAttributeKeys(OtaPackageType firmwareType) {
51 switch (firmwareType) { 49 switch (firmwareType) {
52 case FIRMWARE: 50 case FIRMWARE:
53 return ALL_FW_ATTRIBUTE_KEYS; 51 return ALL_FW_ATTRIBUTE_KEYS;
@@ -57,35 +55,46 @@ public class FirmwareUtil { @@ -57,35 +55,46 @@ public class FirmwareUtil {
57 return Collections.emptyList(); 55 return Collections.emptyList();
58 } 56 }
59 57
60 - public static String getAttributeKey(FirmwareType type, FirmwareKey key) { 58 + public static String getAttributeKey(OtaPackageType type, OtaPackageKey key) {
61 return type.getKeyPrefix() + "_" + key.getValue(); 59 return type.getKeyPrefix() + "_" + key.getValue();
62 } 60 }
63 61
64 - public static String getTargetTelemetryKey(FirmwareType type, FirmwareKey key) { 62 + public static String getTargetTelemetryKey(OtaPackageType type, OtaPackageKey key) {
65 return getTelemetryKey("target_", type, key); 63 return getTelemetryKey("target_", type, key);
66 } 64 }
67 65
68 - public static String getCurrentTelemetryKey(FirmwareType type, FirmwareKey key) { 66 + public static String getCurrentTelemetryKey(OtaPackageType type, OtaPackageKey key) {
69 return getTelemetryKey("current_", type, key); 67 return getTelemetryKey("current_", type, key);
70 } 68 }
71 69
72 - private static String getTelemetryKey(String prefix, FirmwareType type, FirmwareKey key) { 70 + private static String getTelemetryKey(String prefix, OtaPackageType type, OtaPackageKey key) {
73 return prefix + type.getKeyPrefix() + "_" + key.getValue(); 71 return prefix + type.getKeyPrefix() + "_" + key.getValue();
74 } 72 }
75 73
76 - public static String getTelemetryKey(FirmwareType type, FirmwareKey key) { 74 + public static String getTelemetryKey(OtaPackageType type, OtaPackageKey key) {
77 return type.getKeyPrefix() + "_" + key.getValue(); 75 return type.getKeyPrefix() + "_" + key.getValue();
78 } 76 }
79 77
80 - public static FirmwareId getFirmwareId(HasFirmware entity, FirmwareType firmwareType) {  
81 - switch (firmwareType) { 78 + public static OtaPackageId getOtaPackageId(HasOtaPackage entity, OtaPackageType type) {
  79 + switch (type) {
82 case FIRMWARE: 80 case FIRMWARE:
83 return entity.getFirmwareId(); 81 return entity.getFirmwareId();
84 case SOFTWARE: 82 case SOFTWARE:
85 return entity.getSoftwareId(); 83 return entity.getSoftwareId();
86 default: 84 default:
87 - log.warn("Unsupported firmware type: [{}]", firmwareType); 85 + log.warn("Unsupported ota package type: [{}]", type);
88 return null; 86 return null;
89 } 87 }
90 } 88 }
  89 +
  90 + public static <T> T getByOtaPackageType(Supplier<T> firmwareSupplier, Supplier<T> softwareSupplier, OtaPackageType type) {
  91 + switch (type) {
  92 + case FIRMWARE:
  93 + return firmwareSupplier.get();
  94 + case SOFTWARE:
  95 + return softwareSupplier.get();
  96 + default:
  97 + throw new RuntimeException("Unsupported OtaPackage type: " + type);
  98 + }
  99 + }
91 } 100 }
@@ -17,10 +17,11 @@ package org.thingsboard.server.common.data.page; @@ -17,10 +17,11 @@ package org.thingsboard.server.common.data.page;
17 17
18 import com.fasterxml.jackson.annotation.JsonCreator; 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 import com.fasterxml.jackson.annotation.JsonProperty; 19 import com.fasterxml.jackson.annotation.JsonProperty;
20 -import org.thingsboard.server.common.data.BaseData;  
21 20
22 import java.util.Collections; 21 import java.util.Collections;
23 import java.util.List; 22 import java.util.List;
  23 +import java.util.function.Function;
  24 +import java.util.stream.Collectors;
24 25
25 public class PageData<T> { 26 public class PageData<T> {
26 27
@@ -61,4 +62,8 @@ public class PageData<T> { @@ -61,4 +62,8 @@ public class PageData<T> {
61 return hasNext; 62 return hasNext;
62 } 63 }
63 64
  65 + public <D> PageData<D> mapData(Function<T, D> mapper) {
  66 + return new PageData<>(getData().stream().map(mapper).collect(Collectors.toList()), getTotalPages(), getTotalElements(), hasNext());
  67 + }
  68 +
64 } 69 }
@@ -53,6 +53,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura @@ -53,6 +53,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
53 private long maxCreatedAlarms; 53 private long maxCreatedAlarms;
54 54
55 private int defaultStorageTtlDays; 55 private int defaultStorageTtlDays;
  56 + private int alarmsTtlDays;
56 57
57 private double warnThreshold; 58 private double warnThreshold;
58 59
@@ -38,7 +38,7 @@ public class TbKafkaTopicConfigs { @@ -38,7 +38,7 @@ public class TbKafkaTopicConfigs {
38 private String notificationsProperties; 38 private String notificationsProperties;
39 @Value("${queue.kafka.topic-properties.js-executor}") 39 @Value("${queue.kafka.topic-properties.js-executor}")
40 private String jsExecutorProperties; 40 private String jsExecutorProperties;
41 - @Value("${queue.kafka.topic-properties.fw-updates:}") 41 + @Value("${queue.kafka.topic-properties.ota-updates:}")
42 private String fwUpdatesProperties; 42 private String fwUpdatesProperties;
43 43
44 @Getter 44 @Getter
@@ -187,14 +187,14 @@ public class AwsSqsMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng @@ -187,14 +187,14 @@ public class AwsSqsMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
187 } 187 }
188 188
189 @Override 189 @Override
190 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
191 - return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),  
192 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 190 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  191 + return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(),
  192 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
193 } 193 }
194 194
195 @Override 195 @Override
196 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
197 - return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic()); 196 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  197 + return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic());
198 } 198 }
199 199
200 @PreDestroy 200 @PreDestroy
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -177,14 +177,14 @@ public class AwsSqsTbCoreQueueFactory implements TbCoreQueueFactory { @@ -177,14 +177,14 @@ public class AwsSqsTbCoreQueueFactory implements TbCoreQueueFactory {
177 } 177 }
178 178
179 @Override 179 @Override
180 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
181 - return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),  
182 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 180 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  181 + return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(),
  182 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
183 } 183 }
184 184
185 @Override 185 @Override
186 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
187 - return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic()); 186 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  187 + return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic());
188 } 188 }
189 189
190 @PreDestroy 190 @PreDestroy
@@ -131,13 +131,13 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE @@ -131,13 +131,13 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
131 } 131 }
132 132
133 @Override 133 @Override
134 - public TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
135 - return new InMemoryTbQueueConsumer<>(coreSettings.getFirmwareTopic()); 134 + public TbQueueConsumer<TbProtoQueueMsg<TransportProtos.ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  135 + return new InMemoryTbQueueConsumer<>(coreSettings.getOtaPackageTopic());
136 } 136 }
137 137
138 @Override 138 @Override
139 - public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
140 - return new InMemoryTbQueueProducer<>(coreSettings.getFirmwareTopic()); 139 + public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  140 + return new InMemoryTbQueueProducer<>(coreSettings.getOtaPackageTopic());
141 } 141 }
142 142
143 @Override 143 @Override
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -277,24 +277,24 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi @@ -277,24 +277,24 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
277 } 277 }
278 278
279 @Override 279 @Override
280 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
281 - TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder(); 280 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  281 + TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder();
282 consumerBuilder.settings(kafkaSettings); 282 consumerBuilder.settings(kafkaSettings);
283 - consumerBuilder.topic(coreSettings.getFirmwareTopic());  
284 - consumerBuilder.clientId("monolith-fw-consumer-" + serviceInfoProvider.getServiceId());  
285 - consumerBuilder.groupId("monolith-fw-consumer");  
286 - consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 283 + consumerBuilder.topic(coreSettings.getOtaPackageTopic());
  284 + consumerBuilder.clientId("monolith-ota-consumer-" + serviceInfoProvider.getServiceId());
  285 + consumerBuilder.groupId("monolith-ota-consumer");
  286 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
287 consumerBuilder.admin(fwUpdatesAdmin); 287 consumerBuilder.admin(fwUpdatesAdmin);
288 consumerBuilder.statsService(consumerStatsService); 288 consumerBuilder.statsService(consumerStatsService);
289 return consumerBuilder.build(); 289 return consumerBuilder.build();
290 } 290 }
291 291
292 @Override 292 @Override
293 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
294 - TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder(); 293 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  294 + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
295 requestBuilder.settings(kafkaSettings); 295 requestBuilder.settings(kafkaSettings);
296 - requestBuilder.clientId("monolith-fw-producer-" + serviceInfoProvider.getServiceId());  
297 - requestBuilder.defaultTopic(coreSettings.getFirmwareTopic()); 296 + requestBuilder.clientId("monolith-ota-producer-" + serviceInfoProvider.getServiceId());
  297 + requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic());
298 requestBuilder.admin(fwUpdatesAdmin); 298 requestBuilder.admin(fwUpdatesAdmin);
299 return requestBuilder.build(); 299 return requestBuilder.build();
300 } 300 }
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -245,24 +245,24 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { @@ -245,24 +245,24 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
245 } 245 }
246 246
247 @Override 247 @Override
248 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
249 - TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder(); 248 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  249 + TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> consumerBuilder = TbKafkaConsumerTemplate.builder();
250 consumerBuilder.settings(kafkaSettings); 250 consumerBuilder.settings(kafkaSettings);
251 - consumerBuilder.topic(coreSettings.getFirmwareTopic());  
252 - consumerBuilder.clientId("tb-core-fw-consumer-" + serviceInfoProvider.getServiceId());  
253 - consumerBuilder.groupId("tb-core-fw-consumer");  
254 - consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 251 + consumerBuilder.topic(coreSettings.getOtaPackageTopic());
  252 + consumerBuilder.clientId("tb-core-ota-consumer-" + serviceInfoProvider.getServiceId());
  253 + consumerBuilder.groupId("tb-core-ota-consumer");
  254 + consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
255 consumerBuilder.admin(fwUpdatesAdmin); 255 consumerBuilder.admin(fwUpdatesAdmin);
256 consumerBuilder.statsService(consumerStatsService); 256 consumerBuilder.statsService(consumerStatsService);
257 return consumerBuilder.build(); 257 return consumerBuilder.build();
258 } 258 }
259 259
260 @Override 260 @Override
261 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
262 - TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder(); 261 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  262 + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
263 requestBuilder.settings(kafkaSettings); 263 requestBuilder.settings(kafkaSettings);
264 - requestBuilder.clientId("tb-core-fw-producer-" + serviceInfoProvider.getServiceId());  
265 - requestBuilder.defaultTopic(coreSettings.getFirmwareTopic()); 264 + requestBuilder.clientId("tb-core-ota-producer-" + serviceInfoProvider.getServiceId());
  265 + requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic());
266 requestBuilder.admin(fwUpdatesAdmin); 266 requestBuilder.admin(fwUpdatesAdmin);
267 return requestBuilder.build(); 267 return requestBuilder.build();
268 } 268 }
@@ -22,9 +22,9 @@ import org.springframework.stereotype.Component; @@ -22,9 +22,9 @@ import org.springframework.stereotype.Component;
22 import org.thingsboard.server.common.msg.queue.ServiceType; 22 import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest; 23 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
24 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse; 24 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
25 -import org.thingsboard.server.gen.transport.TransportProtos.*;  
26 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 26 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
  27 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
30 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 30 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -192,14 +192,14 @@ public class PubSubMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng @@ -192,14 +192,14 @@ public class PubSubMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
192 } 192 }
193 193
194 @Override 194 @Override
195 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
196 - return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),  
197 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 195 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  196 + return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(),
  197 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
198 } 198 }
199 199
200 @Override 200 @Override
201 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
202 - return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic()); 201 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  202 + return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic());
203 } 203 }
204 204
205 @Override 205 @Override
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -166,14 +166,14 @@ public class PubSubTbCoreQueueFactory implements TbCoreQueueFactory { @@ -166,14 +166,14 @@ public class PubSubTbCoreQueueFactory implements TbCoreQueueFactory {
166 } 166 }
167 167
168 @Override 168 @Override
169 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
170 - return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),  
171 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 169 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  170 + return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(),
  171 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
172 } 172 }
173 173
174 @Override 174 @Override
175 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
176 - return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic()); 175 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  176 + return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic());
177 } 177 }
178 178
179 @Override 179 @Override
@@ -24,7 +24,7 @@ import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest; @@ -24,7 +24,7 @@ import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
24 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse; 24 import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
26 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 26 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
27 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 27 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
30 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 30 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -190,14 +190,14 @@ public class RabbitMqMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE @@ -190,14 +190,14 @@ public class RabbitMqMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
190 } 190 }
191 191
192 @Override 192 @Override
193 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
194 - return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),  
195 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 193 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  194 + return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(),
  195 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
196 } 196 }
197 197
198 @Override 198 @Override
199 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
200 - return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic()); 199 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  200 + return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic());
201 } 201 }
202 202
203 @Override 203 @Override
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -172,14 +172,14 @@ public class RabbitMqTbCoreQueueFactory implements TbCoreQueueFactory { @@ -172,14 +172,14 @@ public class RabbitMqTbCoreQueueFactory implements TbCoreQueueFactory {
172 } 172 }
173 173
174 @Override 174 @Override
175 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
176 - return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),  
177 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 175 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  176 + return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(),
  177 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
178 } 178 }
179 179
180 @Override 180 @Override
181 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
182 - return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic()); 181 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  182 + return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic());
183 } 183 }
184 184
185 @Override 185 @Override
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -189,14 +189,14 @@ public class ServiceBusMonolithQueueFactory implements TbCoreQueueFactory, TbRul @@ -189,14 +189,14 @@ public class ServiceBusMonolithQueueFactory implements TbCoreQueueFactory, TbRul
189 } 189 }
190 190
191 @Override 191 @Override
192 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
193 - return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),  
194 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 192 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  193 + return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(),
  194 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
195 } 195 }
196 196
197 @Override 197 @Override
198 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
199 - return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic()); 198 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  199 + return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic());
200 } 200 }
201 201
202 @Override 202 @Override
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
23 import org.thingsboard.server.gen.js.JsInvokeProtos; 23 import org.thingsboard.server.gen.js.JsInvokeProtos;
24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 25 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
26 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 26 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 27 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; 29 import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -172,14 +172,14 @@ public class ServiceBusTbCoreQueueFactory implements TbCoreQueueFactory { @@ -172,14 +172,14 @@ public class ServiceBusTbCoreQueueFactory implements TbCoreQueueFactory {
172 } 172 }
173 173
174 @Override 174 @Override
175 - public TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer() {  
176 - return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),  
177 - msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders())); 175 + public TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer() {
  176 + return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(),
  177 + msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
178 } 178 }
179 179
180 @Override 180 @Override
181 - public TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer() {  
182 - return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic()); 181 + public TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer() {
  182 + return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic());
183 } 183 }
184 184
185 @Override 185 @Override
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 package org.thingsboard.server.queue.provider; 16 package org.thingsboard.server.queue.provider;
17 17
18 import org.thingsboard.server.gen.js.JsInvokeProtos; 18 import org.thingsboard.server.gen.js.JsInvokeProtos;
19 -import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg; 19 +import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
20 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 20 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
21 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 21 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
22 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; 22 import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
@@ -91,14 +91,14 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory { @@ -91,14 +91,14 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory {
91 * 91 *
92 * @return 92 * @return
93 */ 93 */
94 - TbQueueConsumer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgConsumer(); 94 + TbQueueConsumer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgConsumer();
95 95
96 /** 96 /**
97 * Used to consume messages about firmware update notifications by TB Core Service 97 * Used to consume messages about firmware update notifications by TB Core Service
98 * 98 *
99 * @return 99 * @return
100 */ 100 */
101 - TbQueueProducer<TbProtoQueueMsg<ToFirmwareStateServiceMsg>> createToFirmwareStateServiceMsgProducer(); 101 + TbQueueProducer<TbProtoQueueMsg<ToOtaPackageStateServiceMsg>> createToOtaPackageStateServiceMsgProducer();
102 102
103 /** 103 /**
104 * Used to consume high priority messages by TB Core Service 104 * Used to consume high priority messages by TB Core Service
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.queue.provider; 16 package org.thingsboard.server.queue.provider;
17 17
18 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
19 import org.springframework.stereotype.Service; 18 import org.springframework.stereotype.Service;
20 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; 19 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
21 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; 20 import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
@@ -25,11 +24,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; @@ -25,11 +24,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
25 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; 24 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
26 import org.thingsboard.server.queue.TbQueueProducer; 25 import org.thingsboard.server.queue.TbQueueProducer;
27 import org.thingsboard.server.queue.common.TbProtoQueueMsg; 26 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
  27 +import org.thingsboard.server.queue.util.TbCoreComponent;
28 28
29 import javax.annotation.PostConstruct; 29 import javax.annotation.PostConstruct;
30 30
31 @Service 31 @Service
32 -@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'") 32 +@TbCoreComponent
33 public class TbCoreQueueProducerProvider implements TbQueueProducerProvider { 33 public class TbCoreQueueProducerProvider implements TbQueueProducerProvider {
34 34
35 private final TbCoreQueueFactory tbQueueProvider; 35 private final TbCoreQueueFactory tbQueueProvider;
@@ -26,8 +26,8 @@ public class TbQueueCoreSettings { @@ -26,8 +26,8 @@ public class TbQueueCoreSettings {
26 @Value("${queue.core.topic}") 26 @Value("${queue.core.topic}")
27 private String topic; 27 private String topic;
28 28
29 - @Value("${queue.core.firmware.topic:tb_firmware}")  
30 - private String firmwareTopic; 29 + @Value("${queue.core.ota.topic:tb_ota_package}")
  30 + private String otaPackageTopic;
31 31
32 @Value("${queue.core.usage-stats-topic:tb_usage_stats}") 32 @Value("${queue.core.usage-stats-topic:tb_usage_stats}")
33 private String usageStatsTopic; 33 private String usageStatsTopic;
@@ -137,6 +137,7 @@ message GetAttributeRequestMsg { @@ -137,6 +137,7 @@ message GetAttributeRequestMsg {
137 int32 requestId = 1; 137 int32 requestId = 1;
138 repeated string clientAttributeNames = 2; 138 repeated string clientAttributeNames = 2;
139 repeated string sharedAttributeNames = 3; 139 repeated string sharedAttributeNames = 3;
  140 + bool onlyShared = 4;
140 } 141 }
141 142
142 message GetAttributeResponseMsg { 143 message GetAttributeResponseMsg {
@@ -144,6 +145,7 @@ message GetAttributeResponseMsg { @@ -144,6 +145,7 @@ message GetAttributeResponseMsg {
144 repeated TsKvProto clientAttributeList = 2; 145 repeated TsKvProto clientAttributeList = 2;
145 repeated TsKvProto sharedAttributeList = 3; 146 repeated TsKvProto sharedAttributeList = 3;
146 string error = 5; 147 string error = 5;
  148 + bool sharedStateMsg = 6;
147 } 149 }
148 150
149 message AttributeUpdateNotificationMsg { 151 message AttributeUpdateNotificationMsg {
@@ -386,7 +388,7 @@ enum ResponseStatus { @@ -386,7 +388,7 @@ enum ResponseStatus {
386 FAILURE = 3; 388 FAILURE = 3;
387 } 389 }
388 390
389 -message GetFirmwareRequestMsg { 391 +message GetOtaPackageRequestMsg {
390 int64 deviceIdMSB = 1; 392 int64 deviceIdMSB = 1;
391 int64 deviceIdLSB = 2; 393 int64 deviceIdLSB = 2;
392 int64 tenantIdMSB = 3; 394 int64 tenantIdMSB = 3;
@@ -394,10 +396,10 @@ message GetFirmwareRequestMsg { @@ -394,10 +396,10 @@ message GetFirmwareRequestMsg {
394 string type = 5; 396 string type = 5;
395 } 397 }
396 398
397 -message GetFirmwareResponseMsg { 399 +message GetOtaPackageResponseMsg {
398 ResponseStatus responseStatus = 1; 400 ResponseStatus responseStatus = 1;
399 - int64 firmwareIdMSB = 2;  
400 - int64 firmwareIdLSB = 3; 401 + int64 otaPackageIdMSB = 2;
  402 + int64 otaPackageIdLSB = 3;
401 string type = 4; 403 string type = 4;
402 string title = 5; 404 string title = 5;
403 string version = 6; 405 string version = 6;
@@ -625,7 +627,7 @@ message TransportApiRequestMsg { @@ -625,7 +627,7 @@ message TransportApiRequestMsg {
625 ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7; 627 ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7;
626 ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8; 628 ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8;
627 GetResourceRequestMsg resourceRequestMsg = 9; 629 GetResourceRequestMsg resourceRequestMsg = 9;
628 - GetFirmwareRequestMsg firmwareRequestMsg = 10; 630 + GetOtaPackageRequestMsg otaPackageRequestMsg = 10;
629 GetSnmpDevicesRequestMsg snmpDevicesRequestMsg = 11; 631 GetSnmpDevicesRequestMsg snmpDevicesRequestMsg = 11;
630 GetDeviceRequestMsg deviceRequestMsg = 12; 632 GetDeviceRequestMsg deviceRequestMsg = 12;
631 GetDeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 13; 633 GetDeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 13;
@@ -640,7 +642,7 @@ message TransportApiResponseMsg { @@ -640,7 +642,7 @@ message TransportApiResponseMsg {
640 GetSnmpDevicesResponseMsg snmpDevicesResponseMsg = 5; 642 GetSnmpDevicesResponseMsg snmpDevicesResponseMsg = 5;
641 LwM2MResponseMsg lwM2MResponseMsg = 6; 643 LwM2MResponseMsg lwM2MResponseMsg = 6;
642 GetResourceResponseMsg resourceResponseMsg = 7; 644 GetResourceResponseMsg resourceResponseMsg = 7;
643 - GetFirmwareResponseMsg firmwareResponseMsg = 8; 645 + GetOtaPackageResponseMsg otaPackageResponseMsg = 8;
644 GetDeviceResponseMsg deviceResponseMsg = 9; 646 GetDeviceResponseMsg deviceResponseMsg = 9;
645 GetDeviceCredentialsResponseMsg deviceCredentialsResponseMsg = 10; 647 GetDeviceCredentialsResponseMsg deviceCredentialsResponseMsg = 10;
646 } 648 }
@@ -708,13 +710,13 @@ message ToUsageStatsServiceMsg { @@ -708,13 +710,13 @@ message ToUsageStatsServiceMsg {
708 int64 customerIdLSB = 7; 710 int64 customerIdLSB = 7;
709 } 711 }
710 712
711 -message ToFirmwareStateServiceMsg { 713 +message ToOtaPackageStateServiceMsg {
712 int64 ts = 1; 714 int64 ts = 1;
713 int64 tenantIdMSB = 2; 715 int64 tenantIdMSB = 2;
714 int64 tenantIdLSB = 3; 716 int64 tenantIdLSB = 3;
715 int64 deviceIdMSB = 4; 717 int64 deviceIdMSB = 4;
716 int64 deviceIdLSB = 5; 718 int64 deviceIdLSB = 5;
717 - int64 firmwareIdMSB = 6;  
718 - int64 firmwareIdLSB = 7; 719 + int64 otaPackageIdMSB = 6;
  720 + int64 otaPackageIdLSB = 7;
719 string type = 8; 721 string type = 8;
720 } 722 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap; @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.core.CoapResource; 19 import org.eclipse.californium.core.CoapResource;
20 import org.eclipse.californium.core.coap.CoAP; 20 import org.eclipse.californium.core.coap.CoAP;
  21 +import org.eclipse.californium.core.coap.Response;
21 import org.eclipse.californium.core.server.resources.CoapExchange; 22 import org.eclipse.californium.core.server.resources.CoapExchange;
22 import org.thingsboard.server.common.data.DeviceProfile; 23 import org.thingsboard.server.common.data.DeviceProfile;
23 import org.thingsboard.server.common.transport.TransportContext; 24 import org.thingsboard.server.common.transport.TransportContext;
@@ -56,7 +57,7 @@ public abstract class AbstractCoapTransportResource extends CoapResource { @@ -56,7 +57,7 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
56 57
57 protected abstract void processHandlePost(CoapExchange exchange); 58 protected abstract void processHandlePost(CoapExchange exchange);
58 59
59 - protected void reportActivity(TransportProtos.SessionInfoProto sessionInfo, boolean hasAttributeSubscription, boolean hasRpcSubscription) { 60 + protected void reportSubscriptionInfo(TransportProtos.SessionInfoProto sessionInfo, boolean hasAttributeSubscription, boolean hasRpcSubscription) {
60 transportContext.getTransportService().process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() 61 transportContext.getTransportService().process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder()
61 .setAttributeSubscription(hasAttributeSubscription) 62 .setAttributeSubscription(hasAttributeSubscription)
62 .setRpcSubscription(hasRpcSubscription) 63 .setRpcSubscription(hasRpcSubscription)
@@ -64,6 +65,10 @@ public abstract class AbstractCoapTransportResource extends CoapResource { @@ -64,6 +65,10 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
64 .build(), TransportServiceCallback.EMPTY); 65 .build(), TransportServiceCallback.EMPTY);
65 } 66 }
66 67
  68 + protected void reportActivity(TransportProtos.SessionInfoProto sessionInfo) {
  69 + transportService.reportActivity(sessionInfo);
  70 + }
  71 +
67 protected static TransportProtos.SessionEventMsg getSessionEventMsg(TransportProtos.SessionEvent event) { 72 protected static TransportProtos.SessionEventMsg getSessionEventMsg(TransportProtos.SessionEvent event) {
68 return TransportProtos.SessionEventMsg.newBuilder() 73 return TransportProtos.SessionEventMsg.newBuilder()
69 .setSessionType(TransportProtos.SessionType.ASYNC) 74 .setSessionType(TransportProtos.SessionType.ASYNC)
@@ -112,13 +117,19 @@ public abstract class AbstractCoapTransportResource extends CoapResource { @@ -112,13 +117,19 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
112 117
113 @Override 118 @Override
114 public void onSuccess(Void msg) { 119 public void onSuccess(Void msg) {
115 - exchange.respond(onSuccessResponse); 120 + Response response = new Response(onSuccessResponse);
  121 + response.setAcknowledged(isConRequest());
  122 + exchange.respond(response);
116 } 123 }
117 124
118 @Override 125 @Override
119 public void onError(Throwable e) { 126 public void onError(Throwable e) {
120 exchange.respond(onFailureResponse); 127 exchange.respond(onFailureResponse);
121 } 128 }
  129 +
  130 + private boolean isConRequest() {
  131 + return exchange.advanced().getRequest().isConfirmable();
  132 + }
122 } 133 }
123 134
124 public static class CoapNoOpCallback implements TransportServiceCallback<Void> { 135 public static class CoapNoOpCallback implements TransportServiceCallback<Void> {
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap; @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap;
18 import lombok.Getter; 18 import lombok.Getter;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.beans.factory.annotation.Value;
21 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 22 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
22 import org.springframework.stereotype.Component; 23 import org.springframework.stereotype.Component;
23 import org.thingsboard.server.common.transport.TransportContext; 24 import org.thingsboard.server.common.transport.TransportContext;
@@ -35,6 +36,10 @@ import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor; @@ -35,6 +36,10 @@ import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;
35 public class CoapTransportContext extends TransportContext { 36 public class CoapTransportContext extends TransportContext {
36 37
37 @Getter 38 @Getter
  39 + @Value("${transport.sessions.report_timeout}")
  40 + private long sessionReportTimeout;
  41 +
  42 + @Getter
38 @Autowired 43 @Autowired
39 private JsonCoapAdaptor jsonCoapAdaptor; 44 private JsonCoapAdaptor jsonCoapAdaptor;
40 45
@@ -28,6 +28,7 @@ import org.eclipse.californium.core.observe.ObserveRelation; @@ -28,6 +28,7 @@ import org.eclipse.californium.core.observe.ObserveRelation;
28 import org.eclipse.californium.core.server.resources.CoapExchange; 28 import org.eclipse.californium.core.server.resources.CoapExchange;
29 import org.eclipse.californium.core.server.resources.Resource; 29 import org.eclipse.californium.core.server.resources.Resource;
30 import org.eclipse.californium.core.server.resources.ResourceObserver; 30 import org.eclipse.californium.core.server.resources.ResourceObserver;
  31 +import org.springframework.util.CollectionUtils;
31 import org.thingsboard.server.coapserver.CoapServerService; 32 import org.thingsboard.server.coapserver.CoapServerService;
32 import org.thingsboard.server.coapserver.TbCoapDtlsSessionInfo; 33 import org.thingsboard.server.coapserver.TbCoapDtlsSessionInfo;
33 import org.thingsboard.server.common.data.DataConstants; 34 import org.thingsboard.server.common.data.DataConstants;
@@ -43,7 +44,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC @@ -43,7 +44,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC
43 import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; 44 import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration;
44 import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; 45 import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
45 import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; 46 import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
46 -import org.thingsboard.server.common.data.firmware.FirmwareType; 47 +import org.thingsboard.server.common.data.ota.OtaPackageType;
47 import org.thingsboard.server.common.data.security.DeviceTokenCredentials; 48 import org.thingsboard.server.common.data.security.DeviceTokenCredentials;
48 import org.thingsboard.server.common.msg.session.FeatureType; 49 import org.thingsboard.server.common.msg.session.FeatureType;
49 import org.thingsboard.server.common.msg.session.SessionMsgType; 50 import org.thingsboard.server.common.msg.session.SessionMsgType;
@@ -55,11 +56,14 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -55,11 +56,14 @@ import org.thingsboard.server.gen.transport.TransportProtos;
55 import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor; 56 import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor;
56 57
57 import java.util.List; 58 import java.util.List;
  59 +import java.util.Map;
58 import java.util.Optional; 60 import java.util.Optional;
  61 +import java.util.Random;
59 import java.util.Set; 62 import java.util.Set;
60 import java.util.UUID; 63 import java.util.UUID;
61 import java.util.concurrent.ConcurrentHashMap; 64 import java.util.concurrent.ConcurrentHashMap;
62 import java.util.concurrent.ConcurrentMap; 65 import java.util.concurrent.ConcurrentMap;
  66 +import java.util.concurrent.TimeUnit;
63 import java.util.concurrent.atomic.AtomicInteger; 67 import java.util.concurrent.atomic.AtomicInteger;
64 68
65 @Slf4j 69 @Slf4j
@@ -72,25 +76,30 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -72,25 +76,30 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
72 private static final int REQUEST_ID_POSITION_CERTIFICATE_REQUEST = 4; 76 private static final int REQUEST_ID_POSITION_CERTIFICATE_REQUEST = 4;
73 private static final String DTLS_SESSION_ID_KEY = "DTLS_SESSION_ID"; 77 private static final String DTLS_SESSION_ID_KEY = "DTLS_SESSION_ID";
74 78
75 - private final ConcurrentMap<String, TransportProtos.SessionInfoProto> tokenToSessionIdMap = new ConcurrentHashMap<>();  
76 - private final ConcurrentMap<String, AtomicInteger> tokenToNotificationCounterMap = new ConcurrentHashMap<>(); 79 + private final ConcurrentMap<String, TransportProtos.SessionInfoProto> tokenToSessionInfoMap = new ConcurrentHashMap<>();
  80 + private final ConcurrentMap<String, AtomicInteger> tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>();
  81 + private final ConcurrentMap<TransportProtos.SessionInfoProto, ObserveRelation> sessionInfoToObserveRelationMap = new ConcurrentHashMap<>();
77 private final Set<UUID> rpcSubscriptions = ConcurrentHashMap.newKeySet(); 82 private final Set<UUID> rpcSubscriptions = ConcurrentHashMap.newKeySet();
78 private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet(); 83 private final Set<UUID> attributeSubscriptions = ConcurrentHashMap.newKeySet();
79 84
80 private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap; 85 private ConcurrentMap<String, TbCoapDtlsSessionInfo> dtlsSessionIdMap;
81 private long timeout; 86 private long timeout;
  87 + private long sessionReportTimeout;
82 88
83 - public CoapTransportResource(CoapTransportContext coapTransportContext, CoapServerService coapServerService, String name) {  
84 - super(coapTransportContext, name); 89 + public CoapTransportResource(CoapTransportContext ctx, CoapServerService coapServerService, String name) {
  90 + super(ctx, name);
85 this.setObservable(true); // enable observing 91 this.setObservable(true); // enable observing
86 this.addObserver(new CoapResourceObserver()); 92 this.addObserver(new CoapResourceObserver());
87 this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap(); 93 this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap();
88 this.timeout = coapServerService.getTimeout(); 94 this.timeout = coapServerService.getTimeout();
89 -// this.setObservable(false); // disable observing  
90 -// this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs  
91 -// this.getAttributes().setObservable(); // mark observable in the Link-Format 95 + this.sessionReportTimeout = ctx.getSessionReportTimeout();
  96 + ctx.getScheduler().scheduleAtFixedRate(() -> {
  97 + Set<TransportProtos.SessionInfoProto> observeSessions = sessionInfoToObserveRelationMap.keySet();
  98 + observeSessions.forEach(this::reportActivity);
  99 + }, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS);
92 } 100 }
93 101
  102 + @Override
94 public void checkObserveRelation(Exchange exchange, Response response) { 103 public void checkObserveRelation(Exchange exchange, Response response) {
95 String token = getTokenFromRequest(exchange.getRequest()); 104 String token = getTokenFromRequest(exchange.getRequest());
96 final ObserveRelation relation = exchange.getRelation(); 105 final ObserveRelation relation = exchange.getRelation();
@@ -103,11 +112,20 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -103,11 +112,20 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
103 relation.setEstablished(); 112 relation.setEstablished();
104 addObserveRelation(relation); 113 addObserveRelation(relation);
105 } 114 }
106 - AtomicInteger notificationCounter = tokenToNotificationCounterMap.computeIfAbsent(token, s -> new AtomicInteger(0)); 115 + AtomicInteger notificationCounter = tokenToObserveNotificationSeqMap.computeIfAbsent(token, s -> new AtomicInteger(0));
107 response.getOptions().setObserve(notificationCounter.getAndIncrement()); 116 response.getOptions().setObserve(notificationCounter.getAndIncrement());
108 } // ObserveLayer takes care of the else case 117 } // ObserveLayer takes care of the else case
109 } 118 }
110 119
  120 + public void clearAndNotifyObserveRelation(ObserveRelation relation, CoAP.ResponseCode code) {
  121 + relation.cancel();
  122 + relation.getExchange().sendResponse(new Response(code));
  123 + }
  124 +
  125 + public Map<TransportProtos.SessionInfoProto, ObserveRelation> getSessionInfoToObserveRelationMap() {
  126 + return sessionInfoToObserveRelationMap;
  127 + }
  128 +
111 @Override 129 @Override
112 protected void processHandleGet(CoapExchange exchange) { 130 protected void processHandleGet(CoapExchange exchange) {
113 Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest()); 131 Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest());
@@ -239,7 +257,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -239,7 +257,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
239 } 257 }
240 258
241 private void processRequest(CoapExchange exchange, SessionMsgType type, Request request, TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { 259 private void processRequest(CoapExchange exchange, SessionMsgType type, Request request, TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
242 - UUID sessionId = new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); 260 + UUID sessionId = toSessionId(sessionInfo);
243 try { 261 try {
244 TransportConfigurationContainer transportConfigurationContainer = getTransportConfigurationContainer(deviceProfile); 262 TransportConfigurationContainer transportConfigurationContainer = getTransportConfigurationContainer(deviceProfile);
245 CoapTransportAdaptor coapTransportAdaptor = getCoapTransportAdaptor(transportConfigurationContainer.isJsonPayload()); 263 CoapTransportAdaptor coapTransportAdaptor = getCoapTransportAdaptor(transportConfigurationContainer.isJsonPayload());
@@ -249,14 +267,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -249,14 +267,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
249 coapTransportAdaptor.convertToPostAttributes(sessionId, request, 267 coapTransportAdaptor.convertToPostAttributes(sessionId, request,
250 transportConfigurationContainer.getAttributesMsgDescriptor()), 268 transportConfigurationContainer.getAttributesMsgDescriptor()),
251 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 269 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
252 - reportActivity(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId)); 270 + reportSubscriptionInfo(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
253 break; 271 break;
254 case POST_TELEMETRY_REQUEST: 272 case POST_TELEMETRY_REQUEST:
255 transportService.process(sessionInfo, 273 transportService.process(sessionInfo,
256 coapTransportAdaptor.convertToPostTelemetry(sessionId, request, 274 coapTransportAdaptor.convertToPostTelemetry(sessionId, request,
257 transportConfigurationContainer.getTelemetryMsgDescriptor()), 275 transportConfigurationContainer.getTelemetryMsgDescriptor()),
258 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 276 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
259 - reportActivity(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId)); 277 + reportSubscriptionInfo(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
260 break; 278 break;
261 case CLAIM_REQUEST: 279 case CLAIM_REQUEST:
262 transportService.process(sessionInfo, 280 transportService.process(sessionInfo,
@@ -264,49 +282,52 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -264,49 +282,52 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
264 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 282 new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
265 break; 283 break;
266 case SUBSCRIBE_ATTRIBUTES_REQUEST: 284 case SUBSCRIBE_ATTRIBUTES_REQUEST:
267 - TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); 285 + TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionInfoMap.get(getTokenFromRequest(request));
268 if (currentAttrSession == null) { 286 if (currentAttrSession == null) {
269 attributeSubscriptions.add(sessionId); 287 attributeSubscriptions.add(sessionId);
270 registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, 288 registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor,
271 transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request)); 289 transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request));
272 transportService.process(sessionInfo, 290 transportService.process(sessionInfo,
273 TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), new CoapNoOpCallback(exchange)); 291 TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), new CoapNoOpCallback(exchange));
  292 + transportService.process(sessionInfo,
  293 + TransportProtos.GetAttributeRequestMsg.newBuilder().setOnlyShared(true).build(),
  294 + new CoapNoOpCallback(exchange));
274 } 295 }
275 break; 296 break;
276 case UNSUBSCRIBE_ATTRIBUTES_REQUEST: 297 case UNSUBSCRIBE_ATTRIBUTES_REQUEST:
277 TransportProtos.SessionInfoProto attrSession = lookupAsyncSessionInfo(getTokenFromRequest(request)); 298 TransportProtos.SessionInfoProto attrSession = lookupAsyncSessionInfo(getTokenFromRequest(request));
278 if (attrSession != null) { 299 if (attrSession != null) {
279 - UUID attrSessionId = new UUID(attrSession.getSessionIdMSB(), attrSession.getSessionIdLSB()); 300 + UUID attrSessionId = toSessionId(attrSession);
280 attributeSubscriptions.remove(attrSessionId); 301 attributeSubscriptions.remove(attrSessionId);
  302 + sessionInfoToObserveRelationMap.remove(attrSession);
281 transportService.process(attrSession, 303 transportService.process(attrSession,
282 TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setUnsubscribe(true).build(), 304 TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setUnsubscribe(true).build(),
283 new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 305 new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
284 - closeAndDeregister(sessionInfo, sessionId); 306 + closeAndDeregister(sessionInfo);
285 } 307 }
286 break; 308 break;
287 case SUBSCRIBE_RPC_COMMANDS_REQUEST: 309 case SUBSCRIBE_RPC_COMMANDS_REQUEST:
288 - TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionIdMap.get(getTokenFromRequest(request)); 310 + TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionInfoMap.get(getTokenFromRequest(request));
289 if (currentRpcSession == null) { 311 if (currentRpcSession == null) {
290 rpcSubscriptions.add(sessionId); 312 rpcSubscriptions.add(sessionId);
291 registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor, 313 registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor,
292 transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request)); 314 transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request));
293 transportService.process(sessionInfo, 315 transportService.process(sessionInfo,
294 TransportProtos.SubscribeToRPCMsg.getDefaultInstance(), 316 TransportProtos.SubscribeToRPCMsg.getDefaultInstance(),
295 - new CoapNoOpCallback(exchange));  
296 - } else {  
297 - UUID rpcSessionId = new UUID(currentRpcSession.getSessionIdMSB(), currentRpcSession.getSessionIdLSB());  
298 - reportActivity(currentRpcSession, attributeSubscriptions.contains(rpcSessionId), rpcSubscriptions.contains(rpcSessionId)); 317 + new CoapOkCallback(exchange, CoAP.ResponseCode.VALID, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)
  318 + );
299 } 319 }
300 break; 320 break;
301 case UNSUBSCRIBE_RPC_COMMANDS_REQUEST: 321 case UNSUBSCRIBE_RPC_COMMANDS_REQUEST:
302 TransportProtos.SessionInfoProto rpcSession = lookupAsyncSessionInfo(getTokenFromRequest(request)); 322 TransportProtos.SessionInfoProto rpcSession = lookupAsyncSessionInfo(getTokenFromRequest(request));
303 if (rpcSession != null) { 323 if (rpcSession != null) {
304 - UUID rpcSessionId = new UUID(rpcSession.getSessionIdMSB(), rpcSession.getSessionIdLSB()); 324 + UUID rpcSessionId = toSessionId(rpcSession);
305 rpcSubscriptions.remove(rpcSessionId); 325 rpcSubscriptions.remove(rpcSessionId);
  326 + sessionInfoToObserveRelationMap.remove(rpcSession);
306 transportService.process(rpcSession, 327 transportService.process(rpcSession,
307 TransportProtos.SubscribeToRPCMsg.newBuilder().setUnsubscribe(true).build(), 328 TransportProtos.SubscribeToRPCMsg.newBuilder().setUnsubscribe(true).build(),
308 new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)); 329 new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
309 - closeAndDeregister(sessionInfo, sessionId); 330 + closeAndDeregister(sessionInfo);
310 } 331 }
311 break; 332 break;
312 case TO_DEVICE_RPC_RESPONSE: 333 case TO_DEVICE_RPC_RESPONSE:
@@ -329,10 +350,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -329,10 +350,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
329 new CoapNoOpCallback(exchange)); 350 new CoapNoOpCallback(exchange));
330 break; 351 break;
331 case GET_FIRMWARE_REQUEST: 352 case GET_FIRMWARE_REQUEST:
332 - getFirmwareCallback(sessionInfo, exchange, FirmwareType.FIRMWARE); 353 + getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.FIRMWARE);
333 break; 354 break;
334 case GET_SOFTWARE_REQUEST: 355 case GET_SOFTWARE_REQUEST:
335 - getFirmwareCallback(sessionInfo, exchange, FirmwareType.SOFTWARE); 356 + getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.SOFTWARE);
336 break; 357 break;
337 } 358 }
338 } catch (AdaptorException e) { 359 } catch (AdaptorException e) {
@@ -341,29 +362,33 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -341,29 +362,33 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
341 } 362 }
342 } 363 }
343 364
344 - private void getFirmwareCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, FirmwareType firmwareType) {  
345 - TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() 365 + private UUID toSessionId(TransportProtos.SessionInfoProto sessionInfoProto) {
  366 + return new UUID(sessionInfoProto.getSessionIdMSB(), sessionInfoProto.getSessionIdLSB());
  367 + }
  368 +
  369 + private void getOtaPackageCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, OtaPackageType firmwareType) {
  370 + TransportProtos.GetOtaPackageRequestMsg requestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
346 .setTenantIdMSB(sessionInfo.getTenantIdMSB()) 371 .setTenantIdMSB(sessionInfo.getTenantIdMSB())
347 .setTenantIdLSB(sessionInfo.getTenantIdLSB()) 372 .setTenantIdLSB(sessionInfo.getTenantIdLSB())
348 .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) 373 .setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
349 .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) 374 .setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
350 .setType(firmwareType.name()).build(); 375 .setType(firmwareType.name()).build();
351 - transportContext.getTransportService().process(sessionInfo, requestMsg, new FirmwareCallback(exchange)); 376 + transportContext.getTransportService().process(sessionInfo, requestMsg, new OtaPackageCallback(exchange));
352 } 377 }
353 378
354 private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) { 379 private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) {
355 - tokenToNotificationCounterMap.remove(token);  
356 - return tokenToSessionIdMap.remove(token); 380 + tokenToObserveNotificationSeqMap.remove(token);
  381 + return tokenToSessionInfoMap.remove(token);
357 } 382 }
358 383
359 private void registerAsyncCoapSession(CoapExchange exchange, TransportProtos.SessionInfoProto sessionInfo, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder, String token) { 384 private void registerAsyncCoapSession(CoapExchange exchange, TransportProtos.SessionInfoProto sessionInfo, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder, String token) {
360 - tokenToSessionIdMap.putIfAbsent(token, sessionInfo); 385 + tokenToSessionInfoMap.putIfAbsent(token, sessionInfo);
361 transportService.registerAsyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder)); 386 transportService.registerAsyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder));
362 transportService.process(sessionInfo, getSessionEventMsg(TransportProtos.SessionEvent.OPEN), null); 387 transportService.process(sessionInfo, getSessionEventMsg(TransportProtos.SessionEvent.OPEN), null);
363 } 388 }
364 389
365 private CoapSessionListener getCoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) { 390 private CoapSessionListener getCoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) {
366 - return new CoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder); 391 + return new CoapSessionListener(this, exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder);
367 } 392 }
368 393
369 private String getTokenFromRequest(Request request) { 394 private String getTokenFromRequest(Request request) {
@@ -445,25 +470,25 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -445,25 +470,25 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
445 } 470 }
446 } 471 }
447 472
448 - private class FirmwareCallback implements TransportServiceCallback<TransportProtos.GetFirmwareResponseMsg> { 473 + private class OtaPackageCallback implements TransportServiceCallback<TransportProtos.GetOtaPackageResponseMsg> {
449 private final CoapExchange exchange; 474 private final CoapExchange exchange;
450 475
451 - FirmwareCallback(CoapExchange exchange) { 476 + OtaPackageCallback(CoapExchange exchange) {
452 this.exchange = exchange; 477 this.exchange = exchange;
453 } 478 }
454 479
455 @Override 480 @Override
456 - public void onSuccess(TransportProtos.GetFirmwareResponseMsg msg) { 481 + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg msg) {
457 String title = exchange.getQueryParameter("title"); 482 String title = exchange.getQueryParameter("title");
458 String version = exchange.getQueryParameter("version"); 483 String version = exchange.getQueryParameter("version");
459 if (msg.getResponseStatus().equals(TransportProtos.ResponseStatus.SUCCESS)) { 484 if (msg.getResponseStatus().equals(TransportProtos.ResponseStatus.SUCCESS)) {
460 if (msg.getTitle().equals(title) && msg.getVersion().equals(version)) { 485 if (msg.getTitle().equals(title) && msg.getVersion().equals(version)) {
461 - String firmwareId = new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB()).toString(); 486 + String firmwareId = new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB()).toString();
462 String strChunkSize = exchange.getQueryParameter("size"); 487 String strChunkSize = exchange.getQueryParameter("size");
463 String strChunk = exchange.getQueryParameter("chunk"); 488 String strChunk = exchange.getQueryParameter("chunk");
464 int chunkSize = StringUtils.isEmpty(strChunkSize) ? 0 : Integer.parseInt(strChunkSize); 489 int chunkSize = StringUtils.isEmpty(strChunkSize) ? 0 : Integer.parseInt(strChunkSize);
465 int chunk = StringUtils.isEmpty(strChunk) ? 0 : Integer.parseInt(strChunk); 490 int chunk = StringUtils.isEmpty(strChunk) ? 0 : Integer.parseInt(strChunk);
466 - exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getFirmwareDataCache().get(firmwareId, chunkSize, chunk)); 491 + exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk));
467 } else { 492 } else {
468 exchange.respond(CoAP.ResponseCode.BAD_REQUEST); 493 exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
469 } 494 }
@@ -481,11 +506,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -481,11 +506,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
481 506
482 private static class CoapSessionListener implements SessionMsgListener { 507 private static class CoapSessionListener implements SessionMsgListener {
483 508
  509 + private final CoapTransportResource coapTransportResource;
484 private final CoapExchange exchange; 510 private final CoapExchange exchange;
485 private final CoapTransportAdaptor coapTransportAdaptor; 511 private final CoapTransportAdaptor coapTransportAdaptor;
486 private final DynamicMessage.Builder rpcRequestDynamicMessageBuilder; 512 private final DynamicMessage.Builder rpcRequestDynamicMessageBuilder;
487 513
488 - CoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) { 514 + CoapSessionListener(CoapTransportResource coapTransportResource, CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) {
  515 + this.coapTransportResource = coapTransportResource;
489 this.exchange = exchange; 516 this.exchange = exchange;
490 this.coapTransportAdaptor = coapTransportAdaptor; 517 this.coapTransportAdaptor = coapTransportAdaptor;
491 this.rpcRequestDynamicMessageBuilder = rpcRequestDynamicMessageBuilder; 518 this.rpcRequestDynamicMessageBuilder = rpcRequestDynamicMessageBuilder;
@@ -494,7 +521,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -494,7 +521,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
494 @Override 521 @Override
495 public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg msg) { 522 public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg msg) {
496 try { 523 try {
497 - exchange.respond(coapTransportAdaptor.convertToPublish(msg)); 524 + exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg));
498 } catch (AdaptorException e) { 525 } catch (AdaptorException e) {
499 log.trace("Failed to reply due to error", e); 526 log.trace("Failed to reply due to error", e);
500 exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); 527 exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
@@ -512,8 +539,21 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -512,8 +539,21 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
512 } 539 }
513 540
514 @Override 541 @Override
515 - public void onRemoteSessionCloseCommand(TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {  
516 - exchange.respond(CoAP.ResponseCode.SERVICE_UNAVAILABLE); 542 + public void onRemoteSessionCloseCommand(UUID sessionId, TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
  543 + log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
  544 + Map<TransportProtos.SessionInfoProto, ObserveRelation> sessionToObserveRelationMap = coapTransportResource.getSessionInfoToObserveRelationMap();
  545 + if (coapTransportResource.getObserverCount() > 0 && !CollectionUtils.isEmpty(sessionToObserveRelationMap)) {
  546 + Set<TransportProtos.SessionInfoProto> observeSessions = sessionToObserveRelationMap.keySet();
  547 + Optional<TransportProtos.SessionInfoProto> observeSessionToClose = observeSessions.stream().filter(sessionInfoProto -> {
  548 + UUID observeSessionId = new UUID(sessionInfoProto.getSessionIdMSB(), sessionInfoProto.getSessionIdLSB());
  549 + return observeSessionId.equals(sessionId);
  550 + }).findFirst();
  551 + if (observeSessionToClose.isPresent()) {
  552 + TransportProtos.SessionInfoProto sessionInfoProto = observeSessionToClose.get();
  553 + ObserveRelation observeRelation = sessionToObserveRelationMap.get(sessionInfoProto);
  554 + coapTransportResource.clearAndNotifyObserveRelation(observeRelation, CoAP.ResponseCode.SERVICE_UNAVAILABLE);
  555 + }
  556 + }
517 } 557 }
518 558
519 @Override 559 @Override
@@ -529,7 +569,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -529,7 +569,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
529 @Override 569 @Override
530 public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg msg) { 570 public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg msg) {
531 try { 571 try {
532 - exchange.respond(coapTransportAdaptor.convertToPublish(msg)); 572 + exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg));
533 } catch (AdaptorException e) { 573 } catch (AdaptorException e) {
534 log.trace("Failed to reply due to error", e); 574 log.trace("Failed to reply due to error", e);
535 exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); 575 exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
@@ -561,29 +601,29 @@ public class CoapTransportResource extends AbstractCoapTransportResource { @@ -561,29 +601,29 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
561 601
562 @Override 602 @Override
563 public void addedObserveRelation(ObserveRelation relation) { 603 public void addedObserveRelation(ObserveRelation relation) {
564 - if (log.isTraceEnabled()) {  
565 - Request request = relation.getExchange().getRequest();  
566 - log.trace("Added Observe relation for token: {}", getTokenFromRequest(request));  
567 - } 604 + Request request = relation.getExchange().getRequest();
  605 + String token = getTokenFromRequest(request);
  606 + sessionInfoToObserveRelationMap.putIfAbsent(tokenToSessionInfoMap.get(token), relation);
  607 + log.trace("Added Observe relation for token: {}", token);
568 } 608 }
569 609
570 @Override 610 @Override
571 public void removedObserveRelation(ObserveRelation relation) { 611 public void removedObserveRelation(ObserveRelation relation) {
572 Request request = relation.getExchange().getRequest(); 612 Request request = relation.getExchange().getRequest();
573 - String tokenFromRequest = getTokenFromRequest(request);  
574 - log.trace("Relation removed for token: {}", tokenFromRequest);  
575 - TransportProtos.SessionInfoProto sessionInfoToRemove = lookupAsyncSessionInfo(tokenFromRequest);  
576 - if (sessionInfoToRemove != null) {  
577 - closeAndDeregister(sessionInfoToRemove, new UUID(sessionInfoToRemove.getSessionIdMSB(), sessionInfoToRemove.getDeviceIdLSB()));  
578 - } 613 + String token = getTokenFromRequest(request);
  614 + TransportProtos.SessionInfoProto session = tokenToSessionInfoMap.get(token);
  615 + sessionInfoToObserveRelationMap.remove(session);
  616 + log.trace("Relation removed for token: {}", token);
579 } 617 }
580 } 618 }
581 619
582 - private void closeAndDeregister(TransportProtos.SessionInfoProto session, UUID sessionId) { 620 + private void closeAndDeregister(TransportProtos.SessionInfoProto session) {
  621 + UUID sessionId = toSessionId(session);
583 transportService.process(session, getSessionEventMsg(TransportProtos.SessionEvent.CLOSED), null); 622 transportService.process(session, getSessionEventMsg(TransportProtos.SessionEvent.CLOSED), null);
584 transportService.deregisterSession(session); 623 transportService.deregisterSession(session);
585 rpcSubscriptions.remove(sessionId); 624 rpcSubscriptions.remove(sessionId);
586 attributeSubscriptions.remove(sessionId); 625 attributeSubscriptions.remove(sessionId);
  626 + sessionInfoToObserveRelationMap.remove(session);
587 } 627 }
588 628
589 private TransportConfigurationContainer getTransportConfigurationContainer(DeviceProfile deviceProfile) throws AdaptorException { 629 private TransportConfigurationContainer getTransportConfigurationContainer(DeviceProfile deviceProfile) throws AdaptorException {
@@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j; @@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.core.CoapResource; 19 import org.eclipse.californium.core.CoapResource;
20 import org.eclipse.californium.core.CoapServer; 20 import org.eclipse.californium.core.CoapServer;
21 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
22 -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;  
23 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
24 import org.thingsboard.server.common.data.TbTransportService; 23 import org.thingsboard.server.common.data.TbTransportService;
25 import org.thingsboard.server.coapserver.CoapServerService; 24 import org.thingsboard.server.coapserver.CoapServerService;
@@ -40,6 +40,7 @@ public class CoapAdaptorUtils { @@ -40,6 +40,7 @@ public class CoapAdaptorUtils {
40 result.addAllSharedAttributeNames(sharedKeys); 40 result.addAllSharedAttributeNames(sharedKeys);
41 } 41 }
42 } 42 }
  43 + result.setOnlyShared(false);
43 return result.build(); 44 return result.build();
44 } 45 }
45 46
@@ -39,13 +39,13 @@ public interface CoapTransportAdaptor { @@ -39,13 +39,13 @@ public interface CoapTransportAdaptor {
39 39
40 TransportProtos.ClaimDeviceMsg convertToClaimDevice(UUID sessionId, Request inbound, TransportProtos.SessionInfoProto sessionInfo) throws AdaptorException; 40 TransportProtos.ClaimDeviceMsg convertToClaimDevice(UUID sessionId, Request inbound, TransportProtos.SessionInfoProto sessionInfo) throws AdaptorException;
41 41
42 - Response convertToPublish(TransportProtos.GetAttributeResponseMsg responseMsg) throws AdaptorException; 42 + Response convertToPublish(boolean isConfirmable, TransportProtos.GetAttributeResponseMsg responseMsg) throws AdaptorException;
43 43
44 Response convertToPublish(boolean isConfirmable, TransportProtos.AttributeUpdateNotificationMsg notificationMsg) throws AdaptorException; 44 Response convertToPublish(boolean isConfirmable, TransportProtos.AttributeUpdateNotificationMsg notificationMsg) throws AdaptorException;
45 45
46 Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException; 46 Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException;
47 47
48 - Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException; 48 + Response convertToPublish(boolean isConfirmable, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException;
49 49
50 ProvisionDeviceRequestMsg convertToProvisionRequestMsg(UUID sessionId, Request inbound) throws AdaptorException; 50 ProvisionDeviceRequestMsg convertToProvisionRequestMsg(UUID sessionId, Request inbound) throws AdaptorException;
51 51
@@ -26,12 +26,14 @@ import org.eclipse.californium.core.coap.CoAP; @@ -26,12 +26,14 @@ import org.eclipse.californium.core.coap.CoAP;
26 import org.eclipse.californium.core.coap.Request; 26 import org.eclipse.californium.core.coap.Request;
27 import org.eclipse.californium.core.coap.Response; 27 import org.eclipse.californium.core.coap.Response;
28 import org.springframework.stereotype.Component; 28 import org.springframework.stereotype.Component;
  29 +import org.springframework.util.StringUtils;
29 import org.thingsboard.server.common.data.id.DeviceId; 30 import org.thingsboard.server.common.data.id.DeviceId;
30 import org.thingsboard.server.common.transport.adaptor.AdaptorException; 31 import org.thingsboard.server.common.transport.adaptor.AdaptorException;
31 import org.thingsboard.server.common.transport.adaptor.JsonConverter; 32 import org.thingsboard.server.common.transport.adaptor.JsonConverter;
32 import org.thingsboard.server.gen.transport.TransportProtos; 33 import org.thingsboard.server.gen.transport.TransportProtos;
33 import org.thingsboard.server.transport.coap.CoapTransportResource; 34 import org.thingsboard.server.transport.coap.CoapTransportResource;
34 35
  36 +import java.util.List;
35 import java.util.Optional; 37 import java.util.Optional;
36 import java.util.UUID; 38 import java.util.UUID;
37 39
@@ -101,10 +103,11 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -101,10 +103,11 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
101 } 103 }
102 104
103 @Override 105 @Override
104 - public Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException { 106 + public Response convertToPublish(boolean isConfirmable, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException {
105 Response response = new Response(CoAP.ResponseCode.CONTENT); 107 Response response = new Response(CoAP.ResponseCode.CONTENT);
106 JsonElement result = JsonConverter.toJson(msg); 108 JsonElement result = JsonConverter.toJson(msg);
107 response.setPayload(result.toString()); 109 response.setPayload(result.toString());
  110 + response.setAcknowledged(isConfirmable);
108 return response; 111 return response;
109 } 112 }
110 113
@@ -119,21 +122,35 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -119,21 +122,35 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
119 } 122 }
120 123
121 @Override 124 @Override
122 - public Response convertToPublish(TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {  
123 - if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {  
124 - return new Response(CoAP.ResponseCode.NOT_FOUND); 125 + public Response convertToPublish(boolean isConfirmable, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
  126 + if (msg.getSharedStateMsg()) {
  127 + if (StringUtils.isEmpty(msg.getError())) {
  128 + Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
  129 + response.setAcknowledged(isConfirmable);
  130 + TransportProtos.AttributeUpdateNotificationMsg notificationMsg = TransportProtos.AttributeUpdateNotificationMsg.newBuilder().addAllSharedUpdated(msg.getSharedAttributeListList()).build();
  131 + JsonObject result = JsonConverter.toJson(notificationMsg);
  132 + response.setPayload(result.toString());
  133 + return response;
  134 + } else {
  135 + return new Response(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
  136 + }
125 } else { 137 } else {
126 - Response response = new Response(CoAP.ResponseCode.CONTENT);  
127 - JsonObject result = JsonConverter.toJson(msg);  
128 - response.setPayload(result.toString());  
129 - return response; 138 + if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
  139 + return new Response(CoAP.ResponseCode.NOT_FOUND);
  140 + } else {
  141 + Response response = new Response(CoAP.ResponseCode.CONTENT);
  142 + response.setAcknowledged(isConfirmable);
  143 + JsonObject result = JsonConverter.toJson(msg);
  144 + response.setPayload(result.toString());
  145 + return response;
  146 + }
130 } 147 }
131 } 148 }
132 149
133 private Response getObserveNotification(boolean confirmable, JsonElement json) { 150 private Response getObserveNotification(boolean confirmable, JsonElement json) {
134 - Response response = new Response(CoAP.ResponseCode.CONTENT); 151 + Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
135 response.setPayload(json.toString()); 152 response.setPayload(json.toString());
136 - response.setConfirmable(confirmable); 153 + response.setAcknowledged(confirmable);
137 return response; 154 return response;
138 } 155 }
139 156