diff --git a/application/src/main/data/json/demo/dashboards/firmware.json b/application/src/main/data/json/demo/dashboards/firmware.json
index 6e8d18cd98..4711e34702 100644
--- a/application/src/main/data/json/demo/dashboards/firmware.json
+++ b/application/src/main/data/json/demo/dashboards/firmware.json
@@ -1,5 +1,6 @@
{
"title": "Firmware",
+ "image": null,
"configuration": {
"description": "",
"widgets": {
@@ -247,7 +248,7 @@
"name": "Edit firmware",
"icon": "edit",
"type": "customPretty",
- "customHtml": "
",
+ "customHtml": "",
"customCss": "",
"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}",
"customResources": [],
@@ -257,7 +258,7 @@
"name": "Download firware",
"icon": "file_download",
"type": "custom",
- "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}",
+ "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}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
@@ -1021,7 +1022,7 @@
"name": "Edit firmware",
"icon": "edit",
"type": "customPretty",
- "customHtml": "",
+ "customHtml": "",
"customCss": "",
"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}",
"customResources": [],
@@ -1031,7 +1032,7 @@
"name": "Download firware",
"icon": "file_download",
"type": "custom",
- "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}",
+ "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}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
@@ -1297,7 +1298,7 @@
"name": "Edit firmware",
"icon": "edit",
"type": "customPretty",
- "customHtml": "",
+ "customHtml": "",
"customCss": "",
"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}",
"customResources": [],
@@ -1307,7 +1308,7 @@
"name": "Download firware",
"icon": "file_download",
"type": "custom",
- "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}",
+ "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}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
@@ -1573,7 +1574,7 @@
"name": "Edit firmware",
"icon": "edit",
"type": "customPretty",
- "customHtml": "",
+ "customHtml": "",
"customCss": "",
"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}",
"customResources": [],
@@ -1583,7 +1584,7 @@
"name": "Download firware",
"icon": "file_download",
"type": "custom",
- "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}",
+ "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}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
@@ -1849,7 +1850,7 @@
"name": "Edit firmware",
"icon": "edit",
"type": "customPretty",
- "customHtml": "",
+ "customHtml": "",
"customCss": "",
"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}",
"customResources": [],
@@ -1859,7 +1860,7 @@
"name": "Download firware",
"icon": "file_download",
"type": "custom",
- "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}",
+ "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}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
diff --git a/application/src/main/data/upgrade/3.2.2/schema_update.sql b/application/src/main/data/upgrade/3.2.2/schema_update.sql
index 4fec49130a..2814e18c2f 100644
--- a/application/src/main/data/upgrade/3.2.2/schema_update.sql
+++ b/application/src/main/data/upgrade/3.2.2/schema_update.sql
@@ -59,8 +59,8 @@ CREATE TABLE IF NOT EXISTS resource (
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
);
-CREATE TABLE IF NOT EXISTS firmware (
- id uuid NOT NULL CONSTRAINT firmware_pkey PRIMARY KEY,
+CREATE TABLE IF NOT EXISTS ota_package (
+ id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_profile_id uuid,
@@ -75,7 +75,7 @@ CREATE TABLE IF NOT EXISTS firmware (
data_size bigint,
additional_info varchar,
search_text varchar(255),
- CONSTRAINT firmware_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)
+ CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)
);
ALTER TABLE dashboard
@@ -101,13 +101,13 @@ DO $$
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN
ALTER TABLE device_profile
ADD CONSTRAINT fk_firmware_device_profile
- FOREIGN KEY (firmware_id) REFERENCES firmware(id);
+ FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN
ALTER TABLE device_profile
ADD CONSTRAINT fk_software_device_profile
- FOREIGN KEY (firmware_id) REFERENCES firmware(id);
+ FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN
@@ -119,13 +119,13 @@ DO $$
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN
ALTER TABLE device
ADD CONSTRAINT fk_firmware_device
- FOREIGN KEY (firmware_id) REFERENCES firmware(id);
+ FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN
ALTER TABLE device
ADD CONSTRAINT fk_software_device
- FOREIGN KEY (firmware_id) REFERENCES firmware(id);
+ FOREIGN KEY (firmware_id) REFERENCES ota_package(id);
END IF;
END;
$$;
diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
index 4d94e1051d..5af11d87f5 100644
--- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
@@ -317,25 +317,48 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) {
int requestId = request.getRequestId();
- Futures.addCallback(getAttributesKvEntries(request), new FutureCallback>>() {
- @Override
- public void onSuccess(@Nullable List> result) {
- GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
- .setRequestId(requestId)
- .addAllClientAttributeList(toTsKvProtos(result.get(0)))
- .addAllSharedAttributeList(toTsKvProtos(result.get(1)))
- .build();
- sendToTransport(responseMsg, sessionInfo);
- }
+ if (request.getOnlyShared()) {
+ Futures.addCallback(findAllAttributesByScope(DataConstants.SHARED_SCOPE), new FutureCallback<>() {
+ @Override
+ public void onSuccess(@Nullable List result) {
+ GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
+ .setRequestId(requestId)
+ .setSharedStateMsg(true)
+ .addAllSharedAttributeList(toTsKvProtos(result))
+ .build();
+ sendToTransport(responseMsg, sessionInfo);
+ }
- @Override
- public void onFailure(Throwable t) {
- GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
- .setError(t.getMessage())
- .build();
- sendToTransport(responseMsg, sessionInfo);
- }
- }, MoreExecutors.directExecutor());
+ @Override
+ public void onFailure(Throwable t) {
+ GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
+ .setError(t.getMessage())
+ .setSharedStateMsg(true)
+ .build();
+ sendToTransport(responseMsg, sessionInfo);
+ }
+ }, MoreExecutors.directExecutor());
+ } else {
+ Futures.addCallback(getAttributesKvEntries(request), new FutureCallback<>() {
+ @Override
+ public void onSuccess(@Nullable List> result) {
+ GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
+ .setRequestId(requestId)
+ .addAllClientAttributeList(toTsKvProtos(result.get(0)))
+ .addAllSharedAttributeList(toTsKvProtos(result.get(1)))
+ .build();
+ sendToTransport(responseMsg, sessionInfo);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder()
+ .setError(t.getMessage())
+ .build();
+ sendToTransport(responseMsg, sessionInfo);
+ }
+ }, MoreExecutors.directExecutor());
+ }
}
private ListenableFuture>> getAttributesKvEntries(GetAttributeRequestMsg request) {
@@ -403,9 +426,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
}
if (hasNotificationData) {
AttributeUpdateNotificationMsg finalNotification = notification.build();
- attributeSubscriptions.entrySet().forEach(sub -> {
- sendToTransport(finalNotification, sub.getKey(), sub.getValue().getNodeId());
- });
+ attributeSubscriptions.forEach((key, value) -> sendToTransport(finalNotification, key, value.getNodeId()));
}
} else {
log.debug("[{}] No registered attributes subscriptions to process!", deviceId);
@@ -475,7 +496,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
if (sessions.size() >= systemContext.getMaxConcurrentSessionsPerDevice()) {
UUID sessionIdToRemove = sessions.keySet().stream().findFirst().orElse(null);
if (sessionIdToRemove != null) {
- notifyTransportAboutClosedSession(sessionIdToRemove, sessions.remove(sessionIdToRemove));
+ notifyTransportAboutClosedSession(sessionIdToRemove, sessions.remove(sessionIdToRemove), "max concurrent sessions limit reached per device!");
}
}
sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId())));
@@ -521,7 +542,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
notifyTransportAboutProfileUpdate(k, v, ((DeviceCredentialsUpdateNotificationMsg) msg).getDeviceCredentials());
});
} else {
- sessions.forEach(this::notifyTransportAboutClosedSession);
+ sessions.forEach((sessionId, sessionMd) -> notifyTransportAboutClosedSession(sessionId, sessionMd, "device credentials updated!"));
attributeSubscriptions.clear();
rpcSubscriptions.clear();
dumpSessions();
@@ -529,11 +550,15 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
}
}
- private void notifyTransportAboutClosedSession(UUID sessionId, SessionInfoMetaData sessionMd) {
+ private void notifyTransportAboutClosedSession(UUID sessionId, SessionInfoMetaData sessionMd, String message) {
+ SessionCloseNotificationProto sessionCloseNotificationProto = SessionCloseNotificationProto
+ .newBuilder()
+ .setMessage(message).build();
ToTransportMsg msg = ToTransportMsg.newBuilder()
.setSessionIdMSB(sessionId.getMostSignificantBits())
.setSessionIdLSB(sessionId.getLeastSignificantBits())
- .setSessionCloseNotification(SessionCloseNotificationProto.getDefaultInstance()).build();
+ .setSessionCloseNotification(sessionCloseNotificationProto)
+ .build();
systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
}
@@ -741,7 +766,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
sessions.remove(sessionId);
rpcSubscriptions.remove(sessionId);
attributeSubscriptions.remove(sessionId);
- notifyTransportAboutClosedSession(sessionId, sessionMD);
+ notifyTransportAboutClosedSession(sessionId, sessionMD, "session timeout!");
});
if (!sessionsToRemove.isEmpty()) {
dumpSessions();
diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
index 03883fc167..f0af59c7bc 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
@@ -110,8 +110,11 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- checkAlarmId(alarmId, Operation.WRITE);
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
+ logEntityAction(alarm.getOriginator(), alarm,
+ getCurrentUser().getCustomerId(),
+ ActionType.ALARM_DELETE, null);
sendEntityNotificationMsg(getTenantId(), alarmId, EdgeEventActionType.DELETED);
return alarmService.deleteAlarm(getTenantId(), alarmId);
diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
index e6384c010d..7d41deb2ab 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -31,7 +30,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo;
-import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceInfo;
import org.thingsboard.server.common.data.DeviceProfile;
@@ -39,8 +37,8 @@ import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.EntityViewInfo;
-import org.thingsboard.server.common.data.Firmware;
-import org.thingsboard.server.common.data.FirmwareInfo;
+import org.thingsboard.server.common.data.OtaPackage;
+import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.TbResourceInfo;
@@ -70,7 +68,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TbResourceId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
@@ -79,10 +77,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
-import org.thingsboard.server.common.data.kv.AttributeKvEntry;
-import org.thingsboard.server.common.data.kv.DataType;
-import org.thingsboard.server.common.data.kv.KvEntry;
-import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.page.TimePageLink;
@@ -94,9 +88,6 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
-import org.thingsboard.server.common.msg.TbMsg;
-import org.thingsboard.server.common.msg.TbMsgDataType;
-import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.audit.AuditLogService;
@@ -110,7 +101,7 @@ import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
-import org.thingsboard.server.dao.firmware.FirmwareService;
+import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
@@ -127,8 +118,9 @@ import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.service.action.RuleEngineEntityActionService;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
-import org.thingsboard.server.service.firmware.FirmwareStateService;
+import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.edge.EdgeNotificationService;
import org.thingsboard.server.service.edge.rpc.EdgeGrpcService;
import org.thingsboard.server.service.edge.rpc.init.SyncEdgeService;
@@ -147,11 +139,9 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
-import java.util.stream.Collectors;
import static org.thingsboard.server.dao.service.Validator.validateId;
@@ -250,10 +240,10 @@ public abstract class BaseController {
protected TbResourceService resourceService;
@Autowired
- protected FirmwareService firmwareService;
+ protected OtaPackageService otaPackageService;
@Autowired
- protected FirmwareStateService firmwareStateService;
+ protected OtaPackageStateService otaPackageStateService;
@Autowired
protected TbQueueProducerProvider producerProvider;
@@ -279,6 +269,9 @@ public abstract class BaseController {
@Autowired(required = false)
protected EdgeGrpcService edgeGrpcService;
+ @Autowired
+ protected RuleEngineEntityActionService ruleEngineEntityActionService;
+
@Value("${server.log_controller_error_stack_trace}")
@Getter
private boolean logControllerErrorStackTrace;
@@ -511,8 +504,8 @@ public abstract class BaseController {
case TB_RESOURCE:
checkResourceId(new TbResourceId(entityId.getId()), operation);
return;
- case FIRMWARE:
- checkFirmwareId(new FirmwareId(entityId.getId()), operation);
+ case OTA_PACKAGE:
+ checkOtaPackageId(new OtaPackageId(entityId.getId()), operation);
return;
default:
throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType());
@@ -769,25 +762,25 @@ public abstract class BaseController {
}
}
- Firmware checkFirmwareId(FirmwareId firmwareId, Operation operation) throws ThingsboardException {
+ OtaPackage checkOtaPackageId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException {
try {
- validateId(firmwareId, "Incorrect firmwareId " + firmwareId);
- Firmware firmware = firmwareService.findFirmwareById(getCurrentUser().getTenantId(), firmwareId);
- checkNotNull(firmware);
- accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmware);
- return firmware;
+ validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
+ OtaPackage otaPackage = otaPackageService.findOtaPackageById(getCurrentUser().getTenantId(), otaPackageId);
+ checkNotNull(otaPackage);
+ accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackage);
+ return otaPackage;
} catch (Exception e) {
throw handleException(e, false);
}
}
- FirmwareInfo checkFirmwareInfoId(FirmwareId firmwareId, Operation operation) throws ThingsboardException {
+ OtaPackageInfo checkOtaPackageInfoId(OtaPackageId otaPackageId, Operation operation) throws ThingsboardException {
try {
- validateId(firmwareId, "Incorrect firmwareId " + firmwareId);
- FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(getCurrentUser().getTenantId(), firmwareId);
- checkNotNull(firmwareInfo);
- accessControlService.checkPermission(getCurrentUser(), Resource.FIRMWARE, operation, firmwareId, firmwareInfo);
- return firmwareInfo;
+ validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
+ OtaPackageInfo otaPackageIn = otaPackageService.findOtaPackageInfoById(getCurrentUser().getTenantId(), otaPackageId);
+ checkNotNull(otaPackageIn);
+ accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackageIn);
+ return otaPackageIn;
} catch (Exception e) {
throw handleException(e, false);
}
@@ -809,7 +802,7 @@ public abstract class BaseController {
customerId = user.getCustomerId();
}
if (e == null) {
- pushEntityActionToRuleEngine(entityId, entity, user, customerId, actionType, additionalInfo);
+ ruleEngineEntityActionService.pushEntityActionToRuleEngine(entityId, entity, user.getTenantId(), customerId, actionType, user, additionalInfo);
}
auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo);
}
@@ -819,184 +812,6 @@ public abstract class BaseController {
return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null;
}
- private void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,
- ActionType actionType, Object... additionalInfo) {
- String msgType = null;
- switch (actionType) {
- case ADDED:
- msgType = DataConstants.ENTITY_CREATED;
- break;
- case DELETED:
- msgType = DataConstants.ENTITY_DELETED;
- break;
- case UPDATED:
- msgType = DataConstants.ENTITY_UPDATED;
- break;
- case ASSIGNED_TO_CUSTOMER:
- msgType = DataConstants.ENTITY_ASSIGNED;
- break;
- case UNASSIGNED_FROM_CUSTOMER:
- msgType = DataConstants.ENTITY_UNASSIGNED;
- break;
- case ATTRIBUTES_UPDATED:
- msgType = DataConstants.ATTRIBUTES_UPDATED;
- break;
- case ATTRIBUTES_DELETED:
- msgType = DataConstants.ATTRIBUTES_DELETED;
- break;
- case ALARM_ACK:
- msgType = DataConstants.ALARM_ACK;
- break;
- case ALARM_CLEAR:
- msgType = DataConstants.ALARM_CLEAR;
- break;
- case ASSIGNED_FROM_TENANT:
- msgType = DataConstants.ENTITY_ASSIGNED_FROM_TENANT;
- break;
- case ASSIGNED_TO_TENANT:
- msgType = DataConstants.ENTITY_ASSIGNED_TO_TENANT;
- break;
- case PROVISION_SUCCESS:
- msgType = DataConstants.PROVISION_SUCCESS;
- break;
- case PROVISION_FAILURE:
- msgType = DataConstants.PROVISION_FAILURE;
- break;
- case TIMESERIES_UPDATED:
- msgType = DataConstants.TIMESERIES_UPDATED;
- break;
- case TIMESERIES_DELETED:
- msgType = DataConstants.TIMESERIES_DELETED;
- break;
- case ASSIGNED_TO_EDGE:
- msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;
- break;
- case UNASSIGNED_FROM_EDGE:
- msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;
- break;
- }
- if (!StringUtils.isEmpty(msgType)) {
- try {
- TbMsgMetaData metaData = new TbMsgMetaData();
- metaData.putValue("userId", user.getId().toString());
- metaData.putValue("userName", user.getName());
- if (customerId != null && !customerId.isNullUid()) {
- metaData.putValue("customerId", customerId.toString());
- }
- if (actionType == ActionType.ASSIGNED_TO_CUSTOMER) {
- String strCustomerId = extractParameter(String.class, 1, additionalInfo);
- String strCustomerName = extractParameter(String.class, 2, additionalInfo);
- metaData.putValue("assignedCustomerId", strCustomerId);
- metaData.putValue("assignedCustomerName", strCustomerName);
- } else if (actionType == ActionType.UNASSIGNED_FROM_CUSTOMER) {
- String strCustomerId = extractParameter(String.class, 1, additionalInfo);
- String strCustomerName = extractParameter(String.class, 2, additionalInfo);
- metaData.putValue("unassignedCustomerId", strCustomerId);
- metaData.putValue("unassignedCustomerName", strCustomerName);
- } else if (actionType == ActionType.ASSIGNED_FROM_TENANT) {
- String strTenantId = extractParameter(String.class, 0, additionalInfo);
- String strTenantName = extractParameter(String.class, 1, additionalInfo);
- metaData.putValue("assignedFromTenantId", strTenantId);
- metaData.putValue("assignedFromTenantName", strTenantName);
- } else if (actionType == ActionType.ASSIGNED_TO_TENANT) {
- String strTenantId = extractParameter(String.class, 0, additionalInfo);
- String strTenantName = extractParameter(String.class, 1, additionalInfo);
- metaData.putValue("assignedToTenantId", strTenantId);
- metaData.putValue("assignedToTenantName", strTenantName);
- } else if (actionType == ActionType.ASSIGNED_TO_EDGE) {
- String strEdgeId = extractParameter(String.class, 1, additionalInfo);
- String strEdgeName = extractParameter(String.class, 2, additionalInfo);
- metaData.putValue("assignedEdgeId", strEdgeId);
- metaData.putValue("assignedEdgeName", strEdgeName);
- } else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {
- String strEdgeId = extractParameter(String.class, 1, additionalInfo);
- String strEdgeName = extractParameter(String.class, 2, additionalInfo);
- metaData.putValue("unassignedEdgeId", strEdgeId);
- metaData.putValue("unassignedEdgeName", strEdgeName);
- }
- ObjectNode entityNode;
- if (entity != null) {
- entityNode = json.valueToTree(entity);
- if (entityId.getEntityType() == EntityType.DASHBOARD) {
- entityNode.put("configuration", "");
- }
- } else {
- entityNode = json.createObjectNode();
- if (actionType == ActionType.ATTRIBUTES_UPDATED) {
- String scope = extractParameter(String.class, 0, additionalInfo);
- @SuppressWarnings("unchecked")
- List attributes = extractParameter(List.class, 1, additionalInfo);
- metaData.putValue(DataConstants.SCOPE, scope);
- if (attributes != null) {
- for (AttributeKvEntry attr : attributes) {
- addKvEntry(entityNode, attr);
- }
- }
- } else if (actionType == ActionType.ATTRIBUTES_DELETED) {
- String scope = extractParameter(String.class, 0, additionalInfo);
- @SuppressWarnings("unchecked")
- List keys = extractParameter(List.class, 1, additionalInfo);
- metaData.putValue(DataConstants.SCOPE, scope);
- ArrayNode attrsArrayNode = entityNode.putArray("attributes");
- if (keys != null) {
- keys.forEach(attrsArrayNode::add);
- }
- } else if (actionType == ActionType.TIMESERIES_UPDATED) {
- @SuppressWarnings("unchecked")
- List timeseries = extractParameter(List.class, 0, additionalInfo);
- addTimeseries(entityNode, timeseries);
- } else if (actionType == ActionType.TIMESERIES_DELETED) {
- @SuppressWarnings("unchecked")
- List keys = extractParameter(List.class, 0, additionalInfo);
- if (keys != null) {
- ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
- keys.forEach(timeseriesArrayNode::add);
- }
- entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));
- entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));
- }
- }
- TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
- TenantId tenantId = user.getTenantId();
- if (tenantId.isNullUid()) {
- if (entity instanceof HasTenantId) {
- tenantId = ((HasTenantId) entity).getTenantId();
- }
- }
- tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null);
- } catch (Exception e) {
- log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
- }
- }
- }
-
- private void addKvEntry(ObjectNode entityNode, KvEntry kvEntry) throws Exception {
- if (kvEntry.getDataType() == DataType.BOOLEAN) {
- kvEntry.getBooleanValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
- } else if (kvEntry.getDataType() == DataType.DOUBLE) {
- kvEntry.getDoubleValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
- } else if (kvEntry.getDataType() == DataType.LONG) {
- kvEntry.getLongValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
- } else if (kvEntry.getDataType() == DataType.JSON) {
- if (kvEntry.getJsonValue().isPresent()) {
- entityNode.set(kvEntry.getKey(), json.readTree(kvEntry.getJsonValue().get()));
- }
- } else {
- entityNode.put(kvEntry.getKey(), kvEntry.getValueAsString());
- }
- }
-
- private T extractParameter(Class clazz, int index, Object... additionalInfo) {
- T result = null;
- if (additionalInfo != null && additionalInfo.length > index) {
- Object paramObject = additionalInfo[index];
- if (clazz.isInstance(paramObject)) {
- result = clazz.cast(paramObject);
- }
- }
- return result;
- }
-
protected String entityToStr(E entity) {
try {
return json.writeValueAsString(json.valueToTree(entity));
@@ -1093,23 +908,6 @@ public abstract class BaseController {
return result;
}
- private void addTimeseries(ObjectNode entityNode, List timeseries) throws Exception {
- if (timeseries != null && !timeseries.isEmpty()) {
- ArrayNode result = entityNode.putArray("timeseries");
- Map> groupedTelemetry = timeseries.stream()
- .collect(Collectors.groupingBy(TsKvEntry::getTs));
- for (Map.Entry> entry : groupedTelemetry.entrySet()) {
- ObjectNode element = json.createObjectNode();
- element.put("ts", entry.getKey());
- ObjectNode values = element.putObject("values");
- for (TsKvEntry tsKvEntry : entry.getValue()) {
- addKvEntry(values, tsKvEntry);
- }
- result.add(element);
- }
- }
- }
-
protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException {
String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null;
if (dashboardId != null && !dashboardId.equals("null")) {
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
index 378083b873..b13393515c 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
@@ -75,6 +76,7 @@ import javax.annotation.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import java.util.stream.Collectors;
import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
@@ -153,7 +155,7 @@ public class DeviceController extends BaseController {
deviceStateService.onDeviceUpdated(savedDevice);
}
- firmwareStateService.update(savedDevice, oldDevice);
+ otaPackageStateService.update(savedDevice, oldDevice);
return savedDevice;
} catch (Exception e) {
@@ -778,4 +780,19 @@ public class DeviceController extends BaseController {
throw handleException(e);
}
}
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @RequestMapping(value = "/devices/count/{otaPackageType}", method = RequestMethod.GET)
+ @ResponseBody
+ public Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(@PathVariable("otaPackageType") String otaPackageType,
+ @RequestParam String deviceProfileId) throws ThingsboardException {
+ checkParameter("OtaPackageType", otaPackageType);
+ checkParameter("DeviceProfileId", deviceProfileId);
+ try {
+ return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(
+ getCurrentUser().getTenantId(), new DeviceProfileId(UUID.fromString(deviceProfileId)), OtaPackageType.valueOf(otaPackageType));
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
index 849bcb51b9..ceee45147b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
@@ -168,7 +168,7 @@ public class DeviceProfileController extends BaseController {
null,
created ? ActionType.ADDED : ActionType.UPDATED, null);
- firmwareStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
+ otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(),
deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
diff --git a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java
deleted file mode 100644
index 6728120163..0000000000
--- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Copyright © 2016-2021 The Thingsboard Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.thingsboard.server.controller;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-import org.thingsboard.server.common.data.EntityType;
-import org.thingsboard.server.common.data.Firmware;
-import org.thingsboard.server.common.data.FirmwareInfo;
-import org.thingsboard.server.common.data.audit.ActionType;
-import org.thingsboard.server.common.data.exception.ThingsboardException;
-import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
-import org.thingsboard.server.common.data.page.PageData;
-import org.thingsboard.server.common.data.page.PageLink;
-import org.thingsboard.server.queue.util.TbCoreComponent;
-import org.thingsboard.server.service.security.permission.Operation;
-import org.thingsboard.server.service.security.permission.Resource;
-
-import java.nio.ByteBuffer;
-
-@Slf4j
-@RestController
-@TbCoreComponent
-@RequestMapping("/api")
-public class FirmwareController extends BaseController {
-
- public static final String FIRMWARE_ID = "firmwareId";
- public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm";
-
- @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
- @RequestMapping(value = "/firmware/{firmwareId}/download", method = RequestMethod.GET)
- @ResponseBody
- public ResponseEntity downloadFirmware(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
- checkParameter(FIRMWARE_ID, strFirmwareId);
- try {
- FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
- Firmware firmware = checkFirmwareId(firmwareId, Operation.READ);
-
- ByteArrayResource resource = new ByteArrayResource(firmware.getData().array());
- return ResponseEntity.ok()
- .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmware.getFileName())
- .header("x-filename", firmware.getFileName())
- .contentLength(resource.contentLength())
- .contentType(parseMediaType(firmware.getContentType()))
- .body(resource);
- } catch (Exception e) {
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/firmware/info/{firmwareId}", method = RequestMethod.GET)
- @ResponseBody
- public FirmwareInfo getFirmwareInfoById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
- checkParameter(FIRMWARE_ID, strFirmwareId);
- try {
- FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
- return checkNotNull(firmwareService.findFirmwareInfoById(getTenantId(), firmwareId));
- } catch (Exception e) {
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.GET)
- @ResponseBody
- public Firmware getFirmwareById(@PathVariable(FIRMWARE_ID) String strFirmwareId) throws ThingsboardException {
- checkParameter(FIRMWARE_ID, strFirmwareId);
- try {
- FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
- return checkFirmwareId(firmwareId, Operation.READ);
- } catch (Exception e) {
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/firmware", method = RequestMethod.POST)
- @ResponseBody
- public FirmwareInfo saveFirmwareInfo(@RequestBody FirmwareInfo firmwareInfo) throws ThingsboardException {
- boolean created = firmwareInfo.getId() == null;
- try {
- firmwareInfo.setTenantId(getTenantId());
- checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE);
- FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo);
- logEntityAction(savedFirmwareInfo.getId(), savedFirmwareInfo,
- null, created ? ActionType.ADDED : ActionType.UPDATED, null);
- return savedFirmwareInfo;
- } catch (Exception e) {
- logEntityAction(emptyId(EntityType.FIRMWARE), firmwareInfo,
- null, created ? ActionType.ADDED : ActionType.UPDATED, e);
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.POST)
- @ResponseBody
- public Firmware saveFirmwareData(@PathVariable(FIRMWARE_ID) String strFirmwareId,
- @RequestParam(required = false) String checksum,
- @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
- @RequestBody MultipartFile file) throws ThingsboardException {
- checkParameter(FIRMWARE_ID, strFirmwareId);
- checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr);
- try {
- FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
- FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.READ);
-
- Firmware firmware = new Firmware(firmwareId);
- firmware.setCreatedTime(info.getCreatedTime());
- firmware.setTenantId(getTenantId());
- firmware.setDeviceProfileId(info.getDeviceProfileId());
- firmware.setType(info.getType());
- firmware.setTitle(info.getTitle());
- firmware.setVersion(info.getVersion());
- firmware.setAdditionalInfo(info.getAdditionalInfo());
-
- ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase());
-
- byte[] bytes = file.getBytes();
- if (StringUtils.isEmpty(checksum)) {
- checksum = firmwareService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes));
- }
-
- firmware.setChecksumAlgorithm(checksumAlgorithm);
- firmware.setChecksum(checksum);
- firmware.setFileName(file.getOriginalFilename());
- firmware.setContentType(file.getContentType());
- firmware.setData(ByteBuffer.wrap(bytes));
- firmware.setDataSize((long) bytes.length);
- Firmware savedFirmware = firmwareService.saveFirmware(firmware);
- logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null);
- return savedFirmware;
- } catch (Exception e) {
- logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.UPDATED, e, strFirmwareId);
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/firmwares", method = RequestMethod.GET)
- @ResponseBody
- public PageData getFirmwares(@RequestParam int pageSize,
- @RequestParam int page,
- @RequestParam(required = false) String textSearch,
- @RequestParam(required = false) String sortProperty,
- @RequestParam(required = false) String sortOrder) throws ThingsboardException {
- try {
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- return checkNotNull(firmwareService.findTenantFirmwaresByTenantId(getTenantId(), pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/firmwares/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET)
- @ResponseBody
- public PageData getFirmwares(@PathVariable("deviceProfileId") String strDeviceProfileId,
- @PathVariable("type") String strType,
- @PathVariable("hasData") boolean hasData,
- @RequestParam int pageSize,
- @RequestParam int page,
- @RequestParam(required = false) String textSearch,
- @RequestParam(required = false) String sortProperty,
- @RequestParam(required = false) String sortOrder) throws ThingsboardException {
- checkParameter("deviceProfileId", strDeviceProfileId);
- checkParameter("type", strType);
- try {
- PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
- return checkNotNull(firmwareService.findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(),
- new DeviceProfileId(toUUID(strDeviceProfileId)), FirmwareType.valueOf(strType), hasData, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
- }
-
- @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE)
- @ResponseBody
- public void deleteFirmware(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException {
- checkParameter(FIRMWARE_ID, strFirmwareId);
- try {
- FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
- FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.DELETE);
- firmwareService.deleteFirmware(getTenantId(), firmwareId);
- logEntityAction(firmwareId, info, null, ActionType.DELETED, null, strFirmwareId);
- } catch (Exception e) {
- logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.DELETED, e, strFirmwareId);
- throw handleException(e);
- }
- }
-
-}
diff --git a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java
new file mode 100644
index 0000000000..02e9d4b305
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java
@@ -0,0 +1,222 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.OtaPackage;
+import org.thingsboard.server.common.data.OtaPackageInfo;
+import org.thingsboard.server.common.data.audit.ActionType;
+import org.thingsboard.server.common.data.exception.ThingsboardException;
+import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.id.DeviceProfileId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
+import org.thingsboard.server.common.data.page.PageData;
+import org.thingsboard.server.common.data.page.PageLink;
+import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
+
+import java.nio.ByteBuffer;
+
+@Slf4j
+@RestController
+@TbCoreComponent
+@RequestMapping("/api")
+public class OtaPackageController extends BaseController {
+
+ public static final String OTA_PACKAGE_ID = "otaPackageId";
+ public static final String CHECKSUM_ALGORITHM = "checksumAlgorithm";
+
+ @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')")
+ @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET)
+ @ResponseBody
+ public ResponseEntity downloadOtaPackage(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
+ checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
+ try {
+ OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
+ OtaPackage otaPackage = checkOtaPackageId(otaPackageId, Operation.READ);
+
+ ByteArrayResource resource = new ByteArrayResource(otaPackage.getData().array());
+ return ResponseEntity.ok()
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackage.getFileName())
+ .header("x-filename", otaPackage.getFileName())
+ .contentLength(resource.contentLength())
+ .contentType(parseMediaType(otaPackage.getContentType()))
+ .body(resource);
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET)
+ @ResponseBody
+ public OtaPackageInfo getOtaPackageInfoById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
+ checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
+ try {
+ OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
+ return checkNotNull(otaPackageService.findOtaPackageInfoById(getTenantId(), otaPackageId));
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET)
+ @ResponseBody
+ public OtaPackage getOtaPackageById(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException {
+ checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
+ try {
+ OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
+ return checkOtaPackageId(otaPackageId, Operation.READ);
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @RequestMapping(value = "/otaPackage", method = RequestMethod.POST)
+ @ResponseBody
+ public OtaPackageInfo saveOtaPackageInfo(@RequestBody OtaPackageInfo otaPackageInfo) throws ThingsboardException {
+ boolean created = otaPackageInfo.getId() == null;
+ try {
+ otaPackageInfo.setTenantId(getTenantId());
+ checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE);
+ OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(otaPackageInfo);
+ logEntityAction(savedOtaPackageInfo.getId(), savedOtaPackageInfo,
+ null, created ? ActionType.ADDED : ActionType.UPDATED, null);
+ return savedOtaPackageInfo;
+ } catch (Exception e) {
+ logEntityAction(emptyId(EntityType.OTA_PACKAGE), otaPackageInfo,
+ null, created ? ActionType.ADDED : ActionType.UPDATED, e);
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST)
+ @ResponseBody
+ public OtaPackage saveOtaPackageData(@PathVariable(OTA_PACKAGE_ID) String strOtaPackageId,
+ @RequestParam(required = false) String checksum,
+ @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr,
+ @RequestBody MultipartFile file) throws ThingsboardException {
+ checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
+ checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr);
+ try {
+ OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
+ OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.READ);
+
+ OtaPackage otaPackage = new OtaPackage(otaPackageId);
+ otaPackage.setCreatedTime(info.getCreatedTime());
+ otaPackage.setTenantId(getTenantId());
+ otaPackage.setDeviceProfileId(info.getDeviceProfileId());
+ otaPackage.setType(info.getType());
+ otaPackage.setTitle(info.getTitle());
+ otaPackage.setVersion(info.getVersion());
+ otaPackage.setAdditionalInfo(info.getAdditionalInfo());
+
+ ChecksumAlgorithm checksumAlgorithm = ChecksumAlgorithm.valueOf(checksumAlgorithmStr.toUpperCase());
+
+ byte[] bytes = file.getBytes();
+ if (StringUtils.isEmpty(checksum)) {
+ checksum = otaPackageService.generateChecksum(checksumAlgorithm, ByteBuffer.wrap(bytes));
+ }
+
+ otaPackage.setChecksumAlgorithm(checksumAlgorithm);
+ otaPackage.setChecksum(checksum);
+ otaPackage.setFileName(file.getOriginalFilename());
+ otaPackage.setContentType(file.getContentType());
+ otaPackage.setData(ByteBuffer.wrap(bytes));
+ otaPackage.setDataSize((long) bytes.length);
+ OtaPackage savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage);
+ logEntityAction(savedOtaPackage.getId(), savedOtaPackage, null, ActionType.UPDATED, null);
+ return savedOtaPackage;
+ } catch (Exception e) {
+ logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.UPDATED, e, strOtaPackageId);
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @RequestMapping(value = "/otaPackages", method = RequestMethod.GET)
+ @ResponseBody
+ public PageData getOtaPackages(@RequestParam int pageSize,
+ @RequestParam int page,
+ @RequestParam(required = false) String textSearch,
+ @RequestParam(required = false) String sortProperty,
+ @RequestParam(required = false) String sortOrder) throws ThingsboardException {
+ try {
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink));
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}/{hasData}", method = RequestMethod.GET)
+ @ResponseBody
+ public PageData getOtaPackages(@PathVariable("deviceProfileId") String strDeviceProfileId,
+ @PathVariable("type") String strType,
+ @PathVariable("hasData") boolean hasData,
+ @RequestParam int pageSize,
+ @RequestParam int page,
+ @RequestParam(required = false) String textSearch,
+ @RequestParam(required = false) String sortProperty,
+ @RequestParam(required = false) String sortOrder) throws ThingsboardException {
+ checkParameter("deviceProfileId", strDeviceProfileId);
+ checkParameter("type", strType);
+ try {
+ PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
+ return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(getTenantId(),
+ new DeviceProfileId(toUUID(strDeviceProfileId)), OtaPackageType.valueOf(strType), hasData, pageLink));
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ }
+
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE)
+ @ResponseBody
+ public void deleteOtaPackage(@PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException {
+ checkParameter(OTA_PACKAGE_ID, strOtaPackageId);
+ try {
+ OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId));
+ OtaPackageInfo info = checkOtaPackageInfoId(otaPackageId, Operation.DELETE);
+ otaPackageService.deleteOtaPackage(getTenantId(), otaPackageId);
+ logEntityAction(otaPackageId, info, null, ActionType.DELETED, null, strOtaPackageId);
+ } catch (Exception e) {
+ logEntityAction(emptyId(EntityType.OTA_PACKAGE), null, null, ActionType.DELETED, e, strOtaPackageId);
+ throw handleException(e);
+ }
+ }
+
+}
diff --git a/application/src/main/java/org/thingsboard/server/service/action/RuleEngineEntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/RuleEngineEntityActionService.java
new file mode 100644
index 0000000000..f1320d1a7a
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/action/RuleEngineEntityActionService.java
@@ -0,0 +1,256 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.service.action;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.thingsboard.server.common.data.DataConstants;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.HasName;
+import org.thingsboard.server.common.data.HasTenantId;
+import org.thingsboard.server.common.data.User;
+import org.thingsboard.server.common.data.audit.ActionType;
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.kv.AttributeKvEntry;
+import org.thingsboard.server.common.data.kv.DataType;
+import org.thingsboard.server.common.data.kv.KvEntry;
+import org.thingsboard.server.common.data.kv.TsKvEntry;
+import org.thingsboard.server.common.msg.TbMsg;
+import org.thingsboard.server.common.msg.TbMsgDataType;
+import org.thingsboard.server.common.msg.TbMsgMetaData;
+import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.service.queue.TbClusterService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@TbCoreComponent
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class RuleEngineEntityActionService {
+ private final TbClusterService tbClusterService;
+
+ private static final ObjectMapper json = new ObjectMapper();
+
+ public void pushEntityActionToRuleEngine(EntityId entityId, HasName entity, TenantId tenantId, CustomerId customerId,
+ ActionType actionType, User user, Object... additionalInfo) {
+ String msgType = null;
+ switch (actionType) {
+ case ADDED:
+ msgType = DataConstants.ENTITY_CREATED;
+ break;
+ case DELETED:
+ msgType = DataConstants.ENTITY_DELETED;
+ break;
+ case UPDATED:
+ msgType = DataConstants.ENTITY_UPDATED;
+ break;
+ case ASSIGNED_TO_CUSTOMER:
+ msgType = DataConstants.ENTITY_ASSIGNED;
+ break;
+ case UNASSIGNED_FROM_CUSTOMER:
+ msgType = DataConstants.ENTITY_UNASSIGNED;
+ break;
+ case ATTRIBUTES_UPDATED:
+ msgType = DataConstants.ATTRIBUTES_UPDATED;
+ break;
+ case ATTRIBUTES_DELETED:
+ msgType = DataConstants.ATTRIBUTES_DELETED;
+ break;
+ case ALARM_ACK:
+ msgType = DataConstants.ALARM_ACK;
+ break;
+ case ALARM_CLEAR:
+ msgType = DataConstants.ALARM_CLEAR;
+ break;
+ case ALARM_DELETE:
+ msgType = DataConstants.ALARM_DELETE;
+ break;
+ case ASSIGNED_FROM_TENANT:
+ msgType = DataConstants.ENTITY_ASSIGNED_FROM_TENANT;
+ break;
+ case ASSIGNED_TO_TENANT:
+ msgType = DataConstants.ENTITY_ASSIGNED_TO_TENANT;
+ break;
+ case PROVISION_SUCCESS:
+ msgType = DataConstants.PROVISION_SUCCESS;
+ break;
+ case PROVISION_FAILURE:
+ msgType = DataConstants.PROVISION_FAILURE;
+ break;
+ case TIMESERIES_UPDATED:
+ msgType = DataConstants.TIMESERIES_UPDATED;
+ break;
+ case TIMESERIES_DELETED:
+ msgType = DataConstants.TIMESERIES_DELETED;
+ break;
+ case ASSIGNED_TO_EDGE:
+ msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;
+ break;
+ case UNASSIGNED_FROM_EDGE:
+ msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;
+ break;
+ }
+ if (!StringUtils.isEmpty(msgType)) {
+ try {
+ TbMsgMetaData metaData = new TbMsgMetaData();
+ if (user != null) {
+ metaData.putValue("userId", user.getId().toString());
+ metaData.putValue("userName", user.getName());
+ }
+ if (customerId != null && !customerId.isNullUid()) {
+ metaData.putValue("customerId", customerId.toString());
+ }
+ if (actionType == ActionType.ASSIGNED_TO_CUSTOMER) {
+ String strCustomerId = extractParameter(String.class, 1, additionalInfo);
+ String strCustomerName = extractParameter(String.class, 2, additionalInfo);
+ metaData.putValue("assignedCustomerId", strCustomerId);
+ metaData.putValue("assignedCustomerName", strCustomerName);
+ } else if (actionType == ActionType.UNASSIGNED_FROM_CUSTOMER) {
+ String strCustomerId = extractParameter(String.class, 1, additionalInfo);
+ String strCustomerName = extractParameter(String.class, 2, additionalInfo);
+ metaData.putValue("unassignedCustomerId", strCustomerId);
+ metaData.putValue("unassignedCustomerName", strCustomerName);
+ } else if (actionType == ActionType.ASSIGNED_FROM_TENANT) {
+ String strTenantId = extractParameter(String.class, 0, additionalInfo);
+ String strTenantName = extractParameter(String.class, 1, additionalInfo);
+ metaData.putValue("assignedFromTenantId", strTenantId);
+ metaData.putValue("assignedFromTenantName", strTenantName);
+ } else if (actionType == ActionType.ASSIGNED_TO_TENANT) {
+ String strTenantId = extractParameter(String.class, 0, additionalInfo);
+ String strTenantName = extractParameter(String.class, 1, additionalInfo);
+ metaData.putValue("assignedToTenantId", strTenantId);
+ metaData.putValue("assignedToTenantName", strTenantName);
+ } else if (actionType == ActionType.ASSIGNED_TO_EDGE) {
+ String strEdgeId = extractParameter(String.class, 1, additionalInfo);
+ String strEdgeName = extractParameter(String.class, 2, additionalInfo);
+ metaData.putValue("assignedEdgeId", strEdgeId);
+ metaData.putValue("assignedEdgeName", strEdgeName);
+ } else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {
+ String strEdgeId = extractParameter(String.class, 1, additionalInfo);
+ String strEdgeName = extractParameter(String.class, 2, additionalInfo);
+ metaData.putValue("unassignedEdgeId", strEdgeId);
+ metaData.putValue("unassignedEdgeName", strEdgeName);
+ }
+ ObjectNode entityNode;
+ if (entity != null) {
+ entityNode = json.valueToTree(entity);
+ if (entityId.getEntityType() == EntityType.DASHBOARD) {
+ entityNode.put("configuration", "");
+ }
+ } else {
+ entityNode = json.createObjectNode();
+ if (actionType == ActionType.ATTRIBUTES_UPDATED) {
+ String scope = extractParameter(String.class, 0, additionalInfo);
+ @SuppressWarnings("unchecked")
+ List attributes = extractParameter(List.class, 1, additionalInfo);
+ metaData.putValue(DataConstants.SCOPE, scope);
+ if (attributes != null) {
+ for (AttributeKvEntry attr : attributes) {
+ addKvEntry(entityNode, attr);
+ }
+ }
+ } else if (actionType == ActionType.ATTRIBUTES_DELETED) {
+ String scope = extractParameter(String.class, 0, additionalInfo);
+ @SuppressWarnings("unchecked")
+ List keys = extractParameter(List.class, 1, additionalInfo);
+ metaData.putValue(DataConstants.SCOPE, scope);
+ ArrayNode attrsArrayNode = entityNode.putArray("attributes");
+ if (keys != null) {
+ keys.forEach(attrsArrayNode::add);
+ }
+ } else if (actionType == ActionType.TIMESERIES_UPDATED) {
+ @SuppressWarnings("unchecked")
+ List timeseries = extractParameter(List.class, 0, additionalInfo);
+ addTimeseries(entityNode, timeseries);
+ } else if (actionType == ActionType.TIMESERIES_DELETED) {
+ @SuppressWarnings("unchecked")
+ List keys = extractParameter(List.class, 0, additionalInfo);
+ if (keys != null) {
+ ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
+ keys.forEach(timeseriesArrayNode::add);
+ }
+ entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));
+ entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));
+ }
+ }
+ TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
+ if (tenantId.isNullUid()) {
+ if (entity instanceof HasTenantId) {
+ tenantId = ((HasTenantId) entity).getTenantId();
+ }
+ }
+ tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null);
+ } catch (Exception e) {
+ log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
+ }
+ }
+ }
+
+
+ private T extractParameter(Class clazz, int index, Object... additionalInfo) {
+ T result = null;
+ if (additionalInfo != null && additionalInfo.length > index) {
+ Object paramObject = additionalInfo[index];
+ if (clazz.isInstance(paramObject)) {
+ result = clazz.cast(paramObject);
+ }
+ }
+ return result;
+ }
+
+ private void addTimeseries(ObjectNode entityNode, List timeseries) throws Exception {
+ if (timeseries != null && !timeseries.isEmpty()) {
+ ArrayNode result = entityNode.putArray("timeseries");
+ Map> groupedTelemetry = timeseries.stream()
+ .collect(Collectors.groupingBy(TsKvEntry::getTs));
+ for (Map.Entry> entry : groupedTelemetry.entrySet()) {
+ ObjectNode element = json.createObjectNode();
+ element.put("ts", entry.getKey());
+ ObjectNode values = element.putObject("values");
+ for (TsKvEntry tsKvEntry : entry.getValue()) {
+ addKvEntry(values, tsKvEntry);
+ }
+ result.add(element);
+ }
+ }
+ }
+
+ private void addKvEntry(ObjectNode entityNode, KvEntry kvEntry) throws Exception {
+ if (kvEntry.getDataType() == DataType.BOOLEAN) {
+ kvEntry.getBooleanValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
+ } else if (kvEntry.getDataType() == DataType.DOUBLE) {
+ kvEntry.getDoubleValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
+ } else if (kvEntry.getDataType() == DataType.LONG) {
+ kvEntry.getLongValue().ifPresent(value -> entityNode.put(kvEntry.getKey(), value));
+ } else if (kvEntry.getDataType() == DataType.JSON) {
+ if (kvEntry.getJsonValue().isPresent()) {
+ entityNode.set(kvEntry.getKey(), json.readTree(kvEntry.getJsonValue().get()));
+ }
+ } else {
+ entityNode.put(kvEntry.getKey(), kvEntry.getValueAsString());
+ }
+ }
+}
diff --git a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java
similarity index 69%
rename from application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java
rename to application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java
index 9720cd2097..c5d0c0472f 100644
--- a/application/src/main/java/org/thingsboard/server/service/firmware/DefaultFirmwareStateService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.service.firmware;
+package org.thingsboard.server.service.ota;
import com.google.common.util.concurrent.FutureCallback;
import lombok.extern.slf4j.Slf4j;
@@ -23,12 +23,9 @@ import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
-import org.thingsboard.server.common.data.FirmwareInfo;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;
-import org.thingsboard.server.common.data.firmware.FirmwareUtil;
+import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.id.DeviceId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
@@ -37,13 +34,16 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
+import org.thingsboard.server.common.data.ota.OtaPackageUtil;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
-import org.thingsboard.server.dao.firmware.FirmwareService;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.dao.ota.OtaPackageService;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
@@ -58,44 +58,43 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
-import java.util.function.Function;
-
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.SIZE;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.TITLE;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.TS;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE;
-import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey;
-import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTargetTelemetryKey;
-import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getTelemetryKey;
+
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.CHECKSUM_ALGORITHM;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.SIZE;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.TITLE;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.TS;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.VERSION;
+import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
+import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
+import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey;
+import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTargetTelemetryKey;
+import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getTelemetryKey;
@Slf4j
@Service
@TbCoreComponent
-public class DefaultFirmwareStateService implements FirmwareStateService {
+public class DefaultOtaPackageStateService implements OtaPackageStateService {
private final TbClusterService tbClusterService;
- private final FirmwareService firmwareService;
+ private final OtaPackageService otaPackageService;
private final DeviceService deviceService;
private final DeviceProfileService deviceProfileService;
private final RuleEngineTelemetryService telemetryService;
- private final TbQueueProducer> fwStateMsgProducer;
+ private final TbQueueProducer> otaPackageStateMsgProducer;
- public DefaultFirmwareStateService(TbClusterService tbClusterService, FirmwareService firmwareService,
- DeviceService deviceService,
- DeviceProfileService deviceProfileService,
- RuleEngineTelemetryService telemetryService,
- TbCoreQueueFactory coreQueueFactory) {
+ public DefaultOtaPackageStateService(TbClusterService tbClusterService, OtaPackageService otaPackageService,
+ DeviceService deviceService,
+ DeviceProfileService deviceProfileService,
+ RuleEngineTelemetryService telemetryService,
+ TbCoreQueueFactory coreQueueFactory) {
this.tbClusterService = tbClusterService;
- this.firmwareService = firmwareService;
+ this.otaPackageService = otaPackageService;
this.deviceService = deviceService;
this.deviceProfileService = deviceProfileService;
this.telemetryService = telemetryService;
- this.fwStateMsgProducer = coreQueueFactory.createToFirmwareStateServiceMsgProducer();
+ this.otaPackageStateMsgProducer = coreQueueFactory.createToOtaPackageStateServiceMsgProducer();
}
@Override
@@ -105,14 +104,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
private void updateFirmware(Device device, Device oldDevice) {
- FirmwareId newFirmwareId = device.getFirmwareId();
+ OtaPackageId newFirmwareId = device.getFirmwareId();
if (newFirmwareId == null) {
DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
newFirmwareId = newDeviceProfile.getFirmwareId();
}
if (oldDevice != null) {
if (newFirmwareId != null) {
- FirmwareId oldFirmwareId = oldDevice.getFirmwareId();
+ OtaPackageId oldFirmwareId = oldDevice.getFirmwareId();
if (oldFirmwareId == null) {
DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId());
oldFirmwareId = oldDeviceProfile.getFirmwareId();
@@ -132,14 +131,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
private void updateSoftware(Device device, Device oldDevice) {
- FirmwareId newSoftwareId = device.getSoftwareId();
+ OtaPackageId newSoftwareId = device.getSoftwareId();
if (newSoftwareId == null) {
DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId());
newSoftwareId = newDeviceProfile.getSoftwareId();
}
if (oldDevice != null) {
if (newSoftwareId != null) {
- FirmwareId oldSoftwareId = oldDevice.getSoftwareId();
+ OtaPackageId oldSoftwareId = oldDevice.getSoftwareId();
if (oldSoftwareId == null) {
DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId());
oldSoftwareId = oldDeviceProfile.getSoftwareId();
@@ -170,33 +169,20 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
}
- private void update(TenantId tenantId, DeviceProfile deviceProfile, FirmwareType firmwareType) {
- Function> getDevicesFunction;
+ private void update(TenantId tenantId, DeviceProfile deviceProfile, OtaPackageType otaPackageType) {
Consumer updateConsumer;
- switch (firmwareType) {
- case FIRMWARE:
- getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pl);
- break;
- case SOFTWARE:
- getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId, deviceProfile.getName(), pl);
- break;
- default:
- log.warn("Unsupported firmware type: [{}]", firmwareType);
- return;
- }
-
if (deviceProfile.getFirmwareId() != null) {
long ts = System.currentTimeMillis();
- updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, firmwareType);
+ updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, otaPackageType);
} else {
- updateConsumer = d -> remove(d, firmwareType);
+ updateConsumer = d -> remove(d, otaPackageType);
}
PageLink pageLink = new PageLink(100);
PageData pageData;
do {
- pageData = getDevicesFunction.apply(pageLink);
+ pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyOtaPackage(tenantId, deviceProfile.getId(), otaPackageType, pageLink);
pageData.getData().forEach(updateConsumer);
if (pageData.hasNext()) {
@@ -206,60 +192,60 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
@Override
- public boolean process(ToFirmwareStateServiceMsg msg) {
+ public boolean process(ToOtaPackageStateServiceMsg msg) {
boolean isSuccess = false;
- FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB()));
+ OtaPackageId targetOtaPackageId = new OtaPackageId(new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB()));
DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB()));
TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
- FirmwareType firmwareType = FirmwareType.valueOf(msg.getType());
+ OtaPackageType firmwareType = OtaPackageType.valueOf(msg.getType());
long ts = msg.getTs();
Device device = deviceService.findDeviceById(tenantId, deviceId);
if (device == null) {
log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId);
} else {
- FirmwareId currentFirmwareId = FirmwareUtil.getFirmwareId(device, firmwareType);
- if (currentFirmwareId == null) {
+ OtaPackageId currentOtaPackageId = OtaPackageUtil.getOtaPackageId(device, firmwareType);
+ if (currentOtaPackageId == null) {
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId());
- currentFirmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType);
+ currentOtaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, firmwareType);
}
- if (targetFirmwareId.equals(currentFirmwareId)) {
- update(device, firmwareService.findFirmwareInfoById(device.getTenantId(), targetFirmwareId), ts);
+ if (targetOtaPackageId.equals(currentOtaPackageId)) {
+ update(device, otaPackageService.findOtaPackageInfoById(device.getTenantId(), targetOtaPackageId), ts);
isSuccess = true;
} else {
- log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetFirmwareId, currentFirmwareId);
+ log.warn("[{}] [{}] Can`t update firmware for the device, target firmwareId: [{}], current firmwareId: [{}]!", tenantId, deviceId, targetOtaPackageId, currentOtaPackageId);
}
}
return isSuccess;
}
- private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts, FirmwareType firmwareType) {
- ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder()
+ private void send(TenantId tenantId, DeviceId deviceId, OtaPackageId firmwareId, long ts, OtaPackageType firmwareType) {
+ ToOtaPackageStateServiceMsg msg = ToOtaPackageStateServiceMsg.newBuilder()
.setTenantIdMSB(tenantId.getId().getMostSignificantBits())
.setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
.setDeviceIdMSB(deviceId.getId().getMostSignificantBits())
.setDeviceIdLSB(deviceId.getId().getLeastSignificantBits())
- .setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits())
- .setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits())
+ .setOtaPackageIdMSB(firmwareId.getId().getMostSignificantBits())
+ .setOtaPackageIdLSB(firmwareId.getId().getLeastSignificantBits())
.setType(firmwareType.name())
.setTs(ts)
.build();
- FirmwareInfo firmware = firmwareService.findFirmwareInfoById(tenantId, firmwareId);
+ OtaPackageInfo firmware = otaPackageService.findOtaPackageInfoById(tenantId, firmwareId);
if (firmware == null) {
log.warn("[{}] Failed to send firmware update because firmware was already deleted", firmwareId);
return;
}
- TopicPartitionInfo tpi = new TopicPartitionInfo(fwStateMsgProducer.getDefaultTopic(), null, null, false);
- fwStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
+ TopicPartitionInfo tpi = new TopicPartitionInfo(otaPackageStateMsgProducer.getDefaultTopic(), null, null, false);
+ otaPackageStateMsgProducer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
List telemetry = new ArrayList<>();
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), TITLE), firmware.getTitle())));
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTargetTelemetryKey(firmware.getType(), VERSION), firmware.getVersion())));
telemetry.add(new BasicTsKvEntry(ts, new LongDataEntry(getTargetTelemetryKey(firmware.getType(), TS), ts)));
- telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.QUEUED.name())));
+ telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.QUEUED.name())));
telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() {
@Override
@@ -275,11 +261,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
}
- private void update(Device device, FirmwareInfo firmware, long ts) {
+ private void update(Device device, OtaPackageInfo firmware, long ts) {
TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId();
- BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), FirmwareUpdateStatus.INITIATED.name()));
+ BasicTsKvEntry status = new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(getTelemetryKey(firmware.getType(), STATE), OtaPackageUpdateStatus.INITIATED.name()));
telemetryService.saveAndNotify(tenantId, deviceId, Collections.singletonList(status), new FutureCallback<>() {
@Override
@@ -313,14 +299,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService {
});
}
- private void remove(Device device, FirmwareType firmwareType) {
- telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareUtil.getAttributeKeys(firmwareType),
+ private void remove(Device device, OtaPackageType firmwareType) {
+ telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, OtaPackageUtil.getAttributeKeys(firmwareType),
new FutureCallback<>() {
@Override
public void onSuccess(@Nullable Void tmp) {
log.trace("[{}] Success remove target firmware attributes!", device.getId());
Set keysToNotify = new HashSet<>();
- FirmwareUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key)));
+ OtaPackageUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key)));
tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null);
}
diff --git a/application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java b/application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java
similarity index 79%
rename from application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java
rename to application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java
index 8562f096c9..9392d1c888 100644
--- a/application/src/main/java/org/thingsboard/server/service/firmware/FirmwareStateService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ota/OtaPackageStateService.java
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.service.firmware;
+package org.thingsboard.server.service.ota;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
-public interface FirmwareStateService {
+public interface OtaPackageStateService {
void update(Device device, Device oldDevice);
void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged);
- boolean process(ToFirmwareStateServiceMsg msg);
+ boolean process(ToOtaPackageStateServiceMsg msg);
}
diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
index b8c8698d52..ceb364f921 100644
--- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
+++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
@@ -50,7 +50,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionCloseP
import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.queue.TbQueueConsumer;
@@ -60,7 +60,7 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.edge.EdgeNotificationService;
-import org.thingsboard.server.service.firmware.FirmwareStateService;
+import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.service.queue.processing.AbstractConsumerService;
import org.thingsboard.server.service.queue.processing.IdMsgPair;
@@ -75,7 +75,6 @@ import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWra
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
-import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -101,9 +100,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService> mainConsumer;
@@ -113,10 +112,10 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService> usageStatsConsumer;
- private final TbQueueConsumer> firmwareStatesConsumer;
+ private final TbQueueConsumer> firmwareStatesConsumer;
protected volatile ExecutorService usageStatsExecutor;
@@ -135,11 +134,11 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService {
while (!stopped) {
try {
- List> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration());
+ List> msgs = firmwareStatesConsumer.poll(getNotificationPollDuration());
if (msgs.isEmpty()) {
continue;
}
long timeToSleep = maxProcessingTimeoutPerRecord;
- for (TbProtoQueueMsg msg : msgs) {
+ for (TbProtoQueueMsg msg : msgs) {
try {
long startTime = System.currentTimeMillis();
- boolean isSuccessUpdate = handleFirmwareUpdates(msg);
+ boolean isSuccessUpdate = handleOtaPackageUpdates(msg);
long endTime = System.currentTimeMillis();
long spentTime = endTime - startTime;
timeToSleep = timeToSleep - spentTime;
@@ -402,7 +401,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService msg) {
+ private boolean handleOtaPackageUpdates(TbProtoQueueMsg msg) {
return firmwareStateService.process(msg.getValue());
}
diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
index 15ca6d7be3..2cde0e2113 100644
--- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
+++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
@@ -89,7 +89,7 @@ public class DefaultTbResourceService implements TbResourceService {
} catch (InvalidDDFFileException | IOException e) {
throw new ThingsboardException(e, ThingsboardErrorCode.GENERAL);
}
- if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource) == null) {
+ if (resource.getResourceType().equals(ResourceType.LWM2M_MODEL) && toLwM2mObject(resource, true) == null) {
throw new DataValidationException(String.format("Could not parse the XML of objectModel with name %s", resource.getSearchText()));
}
} else {
@@ -131,7 +131,7 @@ public class DefaultTbResourceService implements TbResourceService {
List resources = resourceService.findTenantResourcesByResourceTypeAndObjectIds(tenantId, ResourceType.LWM2M_MODEL,
objectIds);
return resources.stream()
- .flatMap(s -> Stream.ofNullable(toLwM2mObject(s)))
+ .flatMap(s -> Stream.ofNullable(toLwM2mObject(s, false)))
.sorted(getComparator(sortProperty, sortOrder))
.collect(Collectors.toList());
}
@@ -142,7 +142,7 @@ public class DefaultTbResourceService implements TbResourceService {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
PageData resourcePageData = resourceService.findTenantResourcesByResourceTypeAndPageLink(tenantId, ResourceType.LWM2M_MODEL, pageLink);
return resourcePageData.getData().stream()
- .flatMap(s -> Stream.ofNullable(toLwM2mObject(s)))
+ .flatMap(s -> Stream.ofNullable(toLwM2mObject(s, false)))
.sorted(getComparator(sortProperty, sortOrder))
.collect(Collectors.toList());
}
@@ -167,7 +167,7 @@ public class DefaultTbResourceService implements TbResourceService {
return "DESC".equals(sortOrder) ? comparator.reversed() : comparator;
}
- private LwM2mObject toLwM2mObject(TbResource resource) {
+ private LwM2mObject toLwM2mObject(TbResource resource, boolean isSave) {
try {
DDFFileParser ddfFileParser = new DDFFileParser(new DefaultDDFFileValidator());
List objectModels =
@@ -186,12 +186,16 @@ public class DefaultTbResourceService implements TbResourceService {
instance.setId(0);
List resources = new ArrayList<>();
obj.resources.forEach((k, v) -> {
- if (v.operations.isReadable()) {
+ if (isSave) {
+ LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false);
+ resources.add(lwM2MResourceObserve);
+ }
+ else if (v.operations.isReadable()) {
LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false);
resources.add(lwM2MResourceObserve);
}
});
- if (resources.size() > 0) {
+ if (isSave || resources.size() > 0) {
instance.setResources(resources.toArray(LwM2mResourceObserve[]::new));
lwM2mObject.setInstances(new LwM2mInstance[]{instance});
return lwM2mObject;
diff --git a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
index 914b9ce7fa..540a47e8b0 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
@@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityView;
-import org.thingsboard.server.common.data.FirmwareInfo;
+import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
@@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TbResourceId;
@@ -63,7 +63,7 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
-import org.thingsboard.server.dao.firmware.FirmwareService;
+import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
@@ -135,7 +135,7 @@ public class AccessValidator {
protected ResourceService resourceService;
@Autowired
- protected FirmwareService firmwareService;
+ protected OtaPackageService otaPackageService;
private ExecutorService executor;
@@ -232,8 +232,8 @@ public class AccessValidator {
case TB_RESOURCE:
validateResource(currentUser, operation, entityId, callback);
return;
- case FIRMWARE:
- validateFirmware(currentUser, operation, entityId, callback);
+ case OTA_PACKAGE:
+ validateOtaPackage(currentUser, operation, entityId, callback);
return;
default:
//TODO: add support of other entities
@@ -300,20 +300,20 @@ public class AccessValidator {
}
}
- private void validateFirmware(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback callback) {
+ private void validateOtaPackage(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
- FirmwareInfo firmware = firmwareService.findFirmwareInfoById(currentUser.getTenantId(), new FirmwareId(entityId.getId()));
- if (firmware == null) {
- callback.onSuccess(ValidationResult.entityNotFound("Firmware with requested id wasn't found!"));
+ OtaPackageInfo otaPackage = otaPackageService.findOtaPackageInfoById(currentUser.getTenantId(), new OtaPackageId(entityId.getId()));
+ if (otaPackage == null) {
+ callback.onSuccess(ValidationResult.entityNotFound("OtaPackage with requested id wasn't found!"));
} else {
try {
- accessControlService.checkPermission(currentUser, Resource.FIRMWARE, operation, entityId, firmware);
+ accessControlService.checkPermission(currentUser, Resource.OTA_PACKAGE, operation, entityId, otaPackage);
} catch (ThingsboardException e) {
callback.onSuccess(ValidationResult.accessDenied(e.getMessage()));
}
- callback.onSuccess(ValidationResult.ok(firmware));
+ callback.onSuccess(ValidationResult.ok(otaPackage));
}
}
}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
index 75119c402d..43c420a94a 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
@@ -38,7 +38,7 @@ public enum Resource {
DEVICE_PROFILE(EntityType.DEVICE_PROFILE),
API_USAGE_STATE(EntityType.API_USAGE_STATE),
TB_RESOURCE(EntityType.TB_RESOURCE),
- FIRMWARE(EntityType.FIRMWARE),
+ OTA_PACKAGE(EntityType.OTA_PACKAGE),
EDGE(EntityType.EDGE);
private final EntityType entityType;
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
index af08e38087..8b4d44e938 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
@@ -42,7 +42,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker);
put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker);
put(Resource.TB_RESOURCE, tbResourcePermissionChecker);
- put(Resource.FIRMWARE, tenantEntityPermissionChecker);
+ put(Resource.OTA_PACKAGE, tenantEntityPermissionChecker);
put(Resource.EDGE, tenantEntityPermissionChecker);
}
diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
index bd2df29617..76bbe1f518 100644
--- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
+++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
@@ -26,27 +26,27 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.common.util.JacksonUtil;
-import org.thingsboard.server.cache.firmware.FirmwareDataCache;
+import org.thingsboard.server.cache.ota.OtaPackageDataCache;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityType;
-import org.thingsboard.server.common.data.Firmware;
-import org.thingsboard.server.common.data.FirmwareInfo;
+import org.thingsboard.server.common.data.OtaPackage;
+import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.firmware.FirmwareUtil;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.ota.OtaPackageUtil;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@@ -64,7 +64,7 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
import org.thingsboard.server.dao.device.provision.ProvisionRequest;
import org.thingsboard.server.dao.device.provision.ProvisionResponse;
-import org.thingsboard.server.dao.firmware.FirmwareService;
+import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.gen.transport.TransportProtos;
@@ -124,8 +124,8 @@ public class DefaultTransportApiService implements TransportApiService {
private final DataDecodingEncodingService dataDecodingEncodingService;
private final DeviceProvisionService deviceProvisionService;
private final TbResourceService resourceService;
- private final FirmwareService firmwareService;
- private final FirmwareDataCache firmwareDataCache;
+ private final OtaPackageService otaPackageService;
+ private final OtaPackageDataCache otaPackageDataCache;
private final ConcurrentMap deviceCreationLocks = new ConcurrentHashMap<>();
@@ -134,7 +134,7 @@ public class DefaultTransportApiService implements TransportApiService {
RelationService relationService, DeviceCredentialsService deviceCredentialsService,
DeviceStateService deviceStateService, DbCallbackExecutorService dbCallbackExecutorService,
TbClusterService tbClusterService, DataDecodingEncodingService dataDecodingEncodingService,
- DeviceProvisionService deviceProvisionService, TbResourceService resourceService, FirmwareService firmwareService, FirmwareDataCache firmwareDataCache) {
+ DeviceProvisionService deviceProvisionService, TbResourceService resourceService, OtaPackageService otaPackageService, OtaPackageDataCache otaPackageDataCache) {
this.deviceProfileCache = deviceProfileCache;
this.tenantProfileCache = tenantProfileCache;
this.apiUsageStateService = apiUsageStateService;
@@ -147,8 +147,8 @@ public class DefaultTransportApiService implements TransportApiService {
this.dataDecodingEncodingService = dataDecodingEncodingService;
this.deviceProvisionService = deviceProvisionService;
this.resourceService = resourceService;
- this.firmwareService = firmwareService;
- this.firmwareDataCache = firmwareDataCache;
+ this.otaPackageService = otaPackageService;
+ this.otaPackageDataCache = otaPackageDataCache;
}
@Override
@@ -184,8 +184,8 @@ public class DefaultTransportApiService implements TransportApiService {
result = handle(transportApiRequestMsg.getDeviceRequestMsg());
} else if (transportApiRequestMsg.hasDeviceCredentialsRequestMsg()) {
result = handle(transportApiRequestMsg.getDeviceCredentialsRequestMsg());
- } else if (transportApiRequestMsg.hasFirmwareRequestMsg()) {
- result = handle(transportApiRequestMsg.getFirmwareRequestMsg());
+ } else if (transportApiRequestMsg.hasOtaPackageRequestMsg()) {
+ result = handle(transportApiRequestMsg.getOtaPackageRequestMsg());
}
return Futures.transform(Optional.ofNullable(result).orElseGet(this::getEmptyTransportApiResponseFuture),
@@ -511,50 +511,50 @@ public class DefaultTransportApiService implements TransportApiService {
}
}
- private ListenableFuture handle(TransportProtos.GetFirmwareRequestMsg requestMsg) {
+ private ListenableFuture handle(TransportProtos.GetOtaPackageRequestMsg requestMsg) {
TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
DeviceId deviceId = new DeviceId(new UUID(requestMsg.getDeviceIdMSB(), requestMsg.getDeviceIdLSB()));
- FirmwareType firmwareType = FirmwareType.valueOf(requestMsg.getType());
+ OtaPackageType otaPackageType = OtaPackageType.valueOf(requestMsg.getType());
Device device = deviceService.findDeviceById(tenantId, deviceId);
if (device == null) {
return getEmptyTransportApiResponseFuture();
}
- FirmwareId firmwareId = FirmwareUtil.getFirmwareId(device, firmwareType);
- if (firmwareId == null) {
+ OtaPackageId otaPackageId = OtaPackageUtil.getOtaPackageId(device, otaPackageType);
+ if (otaPackageId == null) {
DeviceProfile deviceProfile = deviceProfileCache.find(device.getDeviceProfileId());
- firmwareId = FirmwareUtil.getFirmwareId(deviceProfile, firmwareType);
+ otaPackageId = OtaPackageUtil.getOtaPackageId(deviceProfile, otaPackageType);
}
- TransportProtos.GetFirmwareResponseMsg.Builder builder = TransportProtos.GetFirmwareResponseMsg.newBuilder();
+ TransportProtos.GetOtaPackageResponseMsg.Builder builder = TransportProtos.GetOtaPackageResponseMsg.newBuilder();
- if (firmwareId == null) {
+ if (otaPackageId == null) {
builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND);
} else {
- FirmwareInfo firmwareInfo = firmwareService.findFirmwareInfoById(tenantId, firmwareId);
+ OtaPackageInfo otaPackageInfo = otaPackageService.findOtaPackageInfoById(tenantId, otaPackageId);
- if (firmwareInfo == null) {
+ if (otaPackageInfo == null) {
builder.setResponseStatus(TransportProtos.ResponseStatus.NOT_FOUND);
} else {
builder.setResponseStatus(TransportProtos.ResponseStatus.SUCCESS);
- builder.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits());
- builder.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits());
- builder.setType(firmwareInfo.getType().name());
- builder.setTitle(firmwareInfo.getTitle());
- builder.setVersion(firmwareInfo.getVersion());
- builder.setFileName(firmwareInfo.getFileName());
- builder.setContentType(firmwareInfo.getContentType());
- if (!firmwareDataCache.has(firmwareId.toString())) {
- Firmware firmware = firmwareService.findFirmwareById(tenantId, firmwareId);
- firmwareDataCache.put(firmwareId.toString(), firmware.getData().array());
+ builder.setOtaPackageIdMSB(otaPackageId.getId().getMostSignificantBits());
+ builder.setOtaPackageIdLSB(otaPackageId.getId().getLeastSignificantBits());
+ builder.setType(otaPackageInfo.getType().name());
+ builder.setTitle(otaPackageInfo.getTitle());
+ builder.setVersion(otaPackageInfo.getVersion());
+ builder.setFileName(otaPackageInfo.getFileName());
+ builder.setContentType(otaPackageInfo.getContentType());
+ if (!otaPackageDataCache.has(otaPackageId.toString())) {
+ OtaPackage otaPackage = otaPackageService.findOtaPackageById(tenantId, otaPackageId);
+ otaPackageDataCache.put(otaPackageId.toString(), otaPackage.getData().array());
}
}
}
return Futures.immediateFuture(
TransportApiResponseMsg.newBuilder()
- .setFirmwareResponseMsg(builder.build())
+ .setOtaPackageResponseMsg(builder.build())
.build());
}
diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java
index 95731d2988..05799fc643 100644
--- a/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ttl/AbstractCleanUpService.java
@@ -17,9 +17,9 @@ package org.thingsboard.server.service.ttl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
-import org.thingsboard.server.dao.util.PsqlDao;
import java.sql.Connection;
+import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
@@ -62,4 +62,8 @@ public abstract class AbstractCleanUpService {
protected abstract void doCleanUp(Connection connection) throws SQLException;
+ protected Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
+ }
+
}
diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/alarms/AlarmsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/alarms/AlarmsCleanUpService.java
new file mode 100644
index 0000000000..3b76a6cbca
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/ttl/alarms/AlarmsCleanUpService.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.service.ttl.alarms;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.thingsboard.server.common.data.alarm.Alarm;
+import org.thingsboard.server.common.data.audit.ActionType;
+import org.thingsboard.server.common.data.id.AlarmId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.page.PageData;
+import org.thingsboard.server.common.data.page.PageLink;
+import org.thingsboard.server.common.data.page.SortOrder;
+import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
+import org.thingsboard.server.common.msg.queue.ServiceType;
+import org.thingsboard.server.dao.alarm.AlarmDao;
+import org.thingsboard.server.dao.alarm.AlarmService;
+import org.thingsboard.server.dao.relation.RelationService;
+import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
+import org.thingsboard.server.dao.tenant.TenantDao;
+import org.thingsboard.server.dao.util.PsqlDao;
+import org.thingsboard.server.queue.discovery.PartitionService;
+import org.thingsboard.server.queue.util.TbCoreComponent;
+import org.thingsboard.server.service.action.RuleEngineEntityActionService;
+import org.thingsboard.server.service.ttl.AbstractCleanUpService;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@TbCoreComponent
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class AlarmsCleanUpService {
+ @Value("${sql.ttl.alarms.removal_batch_size}")
+ private Integer removalBatchSize;
+
+ private final TenantDao tenantDao;
+ private final AlarmDao alarmDao;
+ private final AlarmService alarmService;
+ private final RelationService relationService;
+ private final RuleEngineEntityActionService ruleEngineEntityActionService;
+ private final PartitionService partitionService;
+ private final TbTenantProfileCache tenantProfileCache;
+
+ @Scheduled(initialDelayString = "#{T(org.apache.commons.lang3.RandomUtils).nextLong(0, ${sql.ttl.alarms.checking_interval})}", fixedDelayString = "${sql.ttl.alarms.checking_interval}")
+ public void cleanUp() {
+ PageLink tenantsBatchRequest = new PageLink(10_000, 0);
+ PageLink removalBatchRequest = new PageLink(removalBatchSize, 0 );
+ PageData tenantsIds;
+ do {
+ tenantsIds = tenantDao.findTenantsIds(tenantsBatchRequest);
+ for (TenantId tenantId : tenantsIds.getData()) {
+ if (!partitionService.resolve(ServiceType.TB_CORE, tenantId, tenantId).isMyPartition()) {
+ continue;
+ }
+
+ Optional tenantProfileConfiguration = tenantProfileCache.get(tenantId).getProfileConfiguration();
+ if (tenantProfileConfiguration.isEmpty() || tenantProfileConfiguration.get().getAlarmsTtlDays() == 0) {
+ continue;
+ }
+
+ long ttl = TimeUnit.DAYS.toMillis(tenantProfileConfiguration.get().getAlarmsTtlDays());
+ long expirationTime = System.currentTimeMillis() - ttl;
+
+ long totalRemoved = 0;
+ while (true) {
+ PageData toRemove = alarmDao.findAlarmsIdsByEndTsBeforeAndTenantId(expirationTime, tenantId, removalBatchRequest);
+ toRemove.getData().forEach(alarmId -> {
+ relationService.deleteEntityRelations(tenantId, alarmId);
+ Alarm alarm = alarmService.deleteAlarm(tenantId, alarmId).getAlarm();
+ ruleEngineEntityActionService.pushEntityActionToRuleEngine(alarm.getOriginator(), alarm, tenantId, null, ActionType.ALARM_DELETE, null);
+ });
+
+ totalRemoved += toRemove.getTotalElements();
+ if (!toRemove.hasNext()) {
+ break;
+ }
+ }
+
+ if (totalRemoved > 0) {
+ log.info("Removed {} outdated alarm(s) for tenant {} older than {}", totalRemoved, tenantId, new Date(expirationTime));
+ }
+ }
+
+ tenantsBatchRequest = tenantsBatchRequest.nextPageLink();
+ } while (tenantsIds.hasNext());
+ }
+
+}
diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java
index 0c21719451..e93a82c7eb 100644
--- a/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java
@@ -40,7 +40,7 @@ public class EdgeEventsCleanUpService extends AbstractCleanUpService {
@Scheduled(initialDelayString = "${sql.ttl.edge_events.execution_interval_ms}", fixedDelayString = "${sql.ttl.edge_events.execution_interval_ms}")
public void cleanUp() {
if (ttlTaskExecutionEnabled) {
- try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
+ try (Connection conn = getConnection()) {
doCleanUp(conn);
} catch (SQLException e) {
log.error("SQLException occurred during TTL task execution ", e);
diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java
index 664e01e227..407c88261f 100644
--- a/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ttl/events/EventsCleanUpService.java
@@ -43,7 +43,7 @@ public class EventsCleanUpService extends AbstractCleanUpService {
@Scheduled(initialDelayString = "${sql.ttl.events.execution_interval_ms}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}")
public void cleanUp() {
if (ttlTaskExecutionEnabled) {
- try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
+ try (Connection conn = getConnection()) {
doCleanUp(conn);
} catch (SQLException e) {
log.error("SQLException occurred during TTL task execution ", e);
diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/AbstractTimeseriesCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/AbstractTimeseriesCleanUpService.java
index 9ece0b91a2..ee2d437a22 100644
--- a/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/AbstractTimeseriesCleanUpService.java
+++ b/application/src/main/java/org/thingsboard/server/service/ttl/timeseries/AbstractTimeseriesCleanUpService.java
@@ -36,7 +36,7 @@ public abstract class AbstractTimeseriesCleanUpService extends AbstractCleanUpSe
@Scheduled(initialDelayString = "${sql.ttl.ts.execution_interval_ms}", fixedDelayString = "${sql.ttl.ts.execution_interval_ms}")
public void cleanUp() {
if (ttlTaskExecutionEnabled) {
- try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
+ try (Connection conn = getConnection()) {
doCleanUp(conn);
} catch (SQLException e) {
log.error("SQLException occurred during TTL task execution ", e);
diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml
index 7fde122cf6..78658fe8fd 100644
--- a/application/src/main/resources/thingsboard.yml
+++ b/application/src/main/resources/thingsboard.yml
@@ -273,6 +273,9 @@ sql:
enabled: "${SQL_TTL_EDGE_EVENTS_ENABLED:true}"
execution_interval_ms: "${SQL_TTL_EDGE_EVENTS_EXECUTION_INTERVAL:86400000}" # Number of milliseconds. The current value corresponds to one day
edge_events_ttl: "${SQL_TTL_EDGE_EVENTS_TTL:2628000}" # Number of seconds. The current value corresponds to one month
+ alarms:
+ checking_interval: "${SQL_ALARMS_TTL_CHECKING_INTERVAL:7200000}" # Number of milliseconds. The current value corresponds to two hours
+ removal_batch_size: "${SQL_ALARMS_TTL_REMOVAL_BATCH_SIZE:3000}" # To delete outdated alarms not all at once but in batches
# Actor system parameters
actors:
@@ -371,7 +374,10 @@ caffeine:
tokensOutdatageTime:
timeToLiveInMinutes: 20000
maxSize: 10000
- firmwares:
+ otaPackages:
+ timeToLiveInMinutes: 60
+ maxSize: 10
+ otaPackagesData:
timeToLiveInMinutes: 60
maxSize: 10
edges:
@@ -497,7 +503,7 @@ audit-log:
"device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}"
"edge": "${AUDIT_LOG_MASK_EDGE:W}"
"tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}"
- "firmware": "${AUDIT_LOG_MASK_FIRMWARE:W}"
+ "ota_package": "${AUDIT_LOG_MASK_OTA_PACKAGE:W}"
sink:
# Type of external sink. possible options: none, elasticsearch
type: "${AUDIT_LOG_SINK_TYPE:none}"
@@ -749,7 +755,7 @@ queue:
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\";}"
security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
consumer-properties-per-topic:
- tb_firmware:
+ tb_ota_package:
- key: max.poll.records
value: 10
other:
@@ -759,7 +765,7 @@ queue:
transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1;min.insync.replicas:1}"
js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100;min.insync.replicas:1}"
- fw-updates: "${TB_QUEUE_KAFKA_FW_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}"
+ ota-updates: "${TB_QUEUE_KAFKA_OTA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:10;min.insync.replicas:1}"
consumer-stats:
enabled: "${TB_QUEUE_KAFKA_CONSUMER_STATS_ENABLED:true}"
print-interval-ms: "${TB_QUEUE_KAFKA_CONSUMER_STATS_MIN_PRINT_INTERVAL_MS:60000}"
@@ -830,10 +836,10 @@ queue:
poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:2000}"
- firmware:
- topic: "${TB_QUEUE_CORE_FW_TOPIC:tb_firmware}"
- pack-interval-ms: "${TB_QUEUE_CORE_FW_PACK_INTERVAL_MS:60000}"
- pack-size: "${TB_QUEUE_CORE_FW_PACK_SIZE:100}"
+ ota:
+ topic: "${TB_QUEUE_CORE_OTA_TOPIC:tb_ota_package}"
+ pack-interval-ms: "${TB_QUEUE_CORE_OTA_PACK_INTERVAL_MS:60000}"
+ pack-size: "${TB_QUEUE_CORE_OTA_PACK_SIZE:100}"
usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
stats:
enabled: "${TB_QUEUE_CORE_STATS_ENABLED:true}"
diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java
similarity index 66%
rename from application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java
rename to application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java
index ec36be13a5..9b73053831 100644
--- a/application/src/test/java/org/thingsboard/server/controller/BaseFirmwareControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java
@@ -25,11 +25,10 @@ import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequ
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.DeviceProfile;
-import org.thingsboard.server.common.data.Firmware;
-import org.thingsboard.server.common.data.FirmwareInfo;
+import org.thingsboard.server.common.data.OtaPackage;
+import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@@ -41,11 +40,11 @@ import java.util.Collections;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;
+import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
-public abstract class BaseFirmwareControllerTest extends AbstractControllerTest {
+public abstract class BaseOtaPackageControllerTest extends AbstractControllerTest {
- private IdComparator idComparator = new IdComparator<>();
+ private IdComparator idComparator = new IdComparator<>();
public static final String TITLE = "My firmware";
private static final String FILE_NAME = "filename.txt";
@@ -93,13 +92,13 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
@Test
public void testSaveFirmware() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
Assert.assertNotNull(savedFirmwareInfo);
Assert.assertNotNull(savedFirmwareInfo.getId());
@@ -112,19 +111,19 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
save(savedFirmwareInfo);
- FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class);
+ OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
}
@Test
public void testSaveFirmwareData() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
Assert.assertNotNull(savedFirmwareInfo);
Assert.assertNotNull(savedFirmwareInfo.getId());
@@ -137,12 +136,12 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
save(savedFirmwareInfo);
- FirmwareInfo foundFirmwareInfo = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class);
+ OtaPackageInfo foundFirmwareInfo = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
Assert.assertEquals(foundFirmwareInfo.getTitle(), savedFirmwareInfo.getTitle());
MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
- Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
+ OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
Assert.assertEquals(FILE_NAME, savedFirmware.getFileName());
Assert.assertEquals(CONTENT_TYPE, savedFirmware.getContentType());
@@ -150,97 +149,97 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
@Test
public void testUpdateFirmwareFromDifferentTenant() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
loginDifferentTenant();
- doPost("/api/firmware", savedFirmwareInfo, FirmwareInfo.class, status().isForbidden());
+ doPost("/api/otaPackage", savedFirmwareInfo, OtaPackageInfo.class, status().isForbidden());
deleteDifferentTenant();
}
@Test
public void testFindFirmwareInfoById() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
- FirmwareInfo foundFirmware = doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString(), FirmwareInfo.class);
+ OtaPackageInfo foundFirmware = doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString(), OtaPackageInfo.class);
Assert.assertNotNull(foundFirmware);
Assert.assertEquals(savedFirmwareInfo, foundFirmware);
}
@Test
public void testFindFirmwareById() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
- Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
+ OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
- Firmware foundFirmware = doGet("/api/firmware/" + savedFirmwareInfo.getId().getId().toString(), Firmware.class);
+ OtaPackage foundFirmware = doGet("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString(), OtaPackage.class);
Assert.assertNotNull(foundFirmware);
Assert.assertEquals(savedFirmware, foundFirmware);
}
@Test
public void testDeleteFirmware() throws Exception {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
- doDelete("/api/firmware/" + savedFirmwareInfo.getId().getId().toString())
+ doDelete("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString())
.andExpect(status().isOk());
- doGet("/api/firmware/info/" + savedFirmwareInfo.getId().getId().toString())
+ doGet("/api/otaPackage/info/" + savedFirmwareInfo.getId().getId().toString())
.andExpect(status().isNotFound());
}
@Test
public void testFindTenantFirmwares() throws Exception {
- List firmwares = new ArrayList<>();
+ List otaPackages = new ArrayList<>();
for (int i = 0; i < 165; i++) {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION + i);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
if (i > 100) {
MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
- Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
- firmwares.add(new FirmwareInfo(savedFirmware));
+ OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
+ otaPackages.add(new OtaPackageInfo(savedFirmware));
} else {
- firmwares.add(savedFirmwareInfo);
+ otaPackages.add(savedFirmwareInfo);
}
}
- List loadedFirmwares = new ArrayList<>();
+ List loadedFirmwares = new ArrayList<>();
PageLink pageLink = new PageLink(24);
- PageData pageData;
+ PageData pageData;
do {
- pageData = doGetTypedWithPageLink("/api/firmwares?",
+ pageData = doGetTypedWithPageLink("/api/otaPackages?",
new TypeReference<>() {
}, pageLink);
loadedFirmwares.addAll(pageData.getData());
@@ -249,41 +248,41 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
}
} while (pageData.hasNext());
- Collections.sort(firmwares, idComparator);
+ Collections.sort(otaPackages, idComparator);
Collections.sort(loadedFirmwares, idComparator);
- Assert.assertEquals(firmwares, loadedFirmwares);
+ Assert.assertEquals(otaPackages, loadedFirmwares);
}
@Test
public void testFindTenantFirmwaresByHasData() throws Exception {
- List firmwaresWithData = new ArrayList<>();
- List firmwaresWithoutData = new ArrayList<>();
+ List otaPackagesWithData = new ArrayList<>();
+ List otaPackagesWithoutData = new ArrayList<>();
for (int i = 0; i < 165; i++) {
- FirmwareInfo firmwareInfo = new FirmwareInfo();
+ OtaPackageInfo firmwareInfo = new OtaPackageInfo();
firmwareInfo.setDeviceProfileId(deviceProfileId);
firmwareInfo.setType(FIRMWARE);
firmwareInfo.setTitle(TITLE);
firmwareInfo.setVersion(VERSION + i);
- FirmwareInfo savedFirmwareInfo = save(firmwareInfo);
+ OtaPackageInfo savedFirmwareInfo = save(firmwareInfo);
if (i > 100) {
MockMultipartFile testData = new MockMultipartFile("file", FILE_NAME, CONTENT_TYPE, DATA.array());
- Firmware savedFirmware = savaData("/api/firmware/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
- firmwaresWithData.add(new FirmwareInfo(savedFirmware));
+ OtaPackage savedFirmware = savaData("/api/otaPackage/" + savedFirmwareInfo.getId().getId().toString() + "?checksum={checksum}&checksumAlgorithm={checksumAlgorithm}", testData, CHECKSUM, CHECKSUM_ALGORITHM);
+ otaPackagesWithData.add(new OtaPackageInfo(savedFirmware));
} else {
- firmwaresWithoutData.add(savedFirmwareInfo);
+ otaPackagesWithoutData.add(savedFirmwareInfo);
}
}
- List loadedFirmwaresWithData = new ArrayList<>();
+ List loadedFirmwaresWithData = new ArrayList<>();
PageLink pageLink = new PageLink(24);
- PageData pageData;
+ PageData pageData;
do {
- pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/true?",
+ pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/true?",
new TypeReference<>() {
}, pageLink);
loadedFirmwaresWithData.addAll(pageData.getData());
@@ -292,10 +291,10 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
}
} while (pageData.hasNext());
- List loadedFirmwaresWithoutData = new ArrayList<>();
+ List loadedFirmwaresWithoutData = new ArrayList<>();
pageLink = new PageLink(24);
do {
- pageData = doGetTypedWithPageLink("/api/firmwares/" + deviceProfileId.toString() + "/FIRMWARE/false?",
+ pageData = doGetTypedWithPageLink("/api/otaPackages/" + deviceProfileId.toString() + "/FIRMWARE/false?",
new TypeReference<>() {
}, pageLink);
loadedFirmwaresWithoutData.addAll(pageData.getData());
@@ -304,25 +303,25 @@ public abstract class BaseFirmwareControllerTest extends AbstractControllerTest
}
} while (pageData.hasNext());
- Collections.sort(firmwaresWithData, idComparator);
- Collections.sort(firmwaresWithoutData, idComparator);
+ Collections.sort(otaPackagesWithData, idComparator);
+ Collections.sort(otaPackagesWithoutData, idComparator);
Collections.sort(loadedFirmwaresWithData, idComparator);
Collections.sort(loadedFirmwaresWithoutData, idComparator);
- Assert.assertEquals(firmwaresWithData, loadedFirmwaresWithData);
- Assert.assertEquals(firmwaresWithoutData, loadedFirmwaresWithoutData);
+ Assert.assertEquals(otaPackagesWithData, loadedFirmwaresWithData);
+ Assert.assertEquals(otaPackagesWithoutData, loadedFirmwaresWithoutData);
}
- private FirmwareInfo save(FirmwareInfo firmwareInfo) throws Exception {
- return doPost("/api/firmware", firmwareInfo, FirmwareInfo.class);
+ private OtaPackageInfo save(OtaPackageInfo firmwareInfo) throws Exception {
+ return doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class);
}
- protected Firmware savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception {
+ protected OtaPackage savaData(String urlTemplate, MockMultipartFile content, String... params) throws Exception {
MockMultipartHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.multipart(urlTemplate, params);
postRequest.file(content);
setJwtToken(postRequest);
- return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), Firmware.class);
+ return readResponse(mockMvc.perform(postRequest).andExpect(status().isOk()), OtaPackage.class);
}
}
diff --git a/application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java b/application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java
similarity index 82%
rename from application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java
rename to application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java
index a0e4a838ca..92bd9ba9c6 100644
--- a/application/src/test/java/org/thingsboard/server/controller/sql/FirmwareControllerSqlTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/sql/OtaPackageControllerSqlTest.java
@@ -15,9 +15,9 @@
*/
package org.thingsboard.server.controller.sql;
-import org.thingsboard.server.controller.BaseFirmwareControllerTest;
+import org.thingsboard.server.controller.BaseOtaPackageControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
@DaoSqlTest
-public class FirmwareControllerSqlTest extends BaseFirmwareControllerTest {
+public class OtaPackageControllerSqlTest extends BaseOtaPackageControllerTest {
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesIntegrationTest.java
index faa6aae5c4..5286accd09 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesIntegrationTest.java
@@ -44,6 +44,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}";
+ protected static final String POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION = "{\"attribute1\":\"value\",\"attribute2\":false,\"attribute3\":41.0,\"attribute4\":72," +
+ "\"attribute5\":{\"someNumber\":41,\"someArray\":[],\"someNestedObject\":{\"key\":\"value\"}}}";
+
@Before
public void beforeTest() throws Exception {
processBeforeTest("Test Subscribe to attribute updates", null, null);
@@ -56,50 +59,85 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
@Test
public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
- processTestSubscribeToAttributesUpdates();
+ processTestSubscribeToAttributesUpdates(false);
}
- protected void processTestSubscribeToAttributesUpdates() throws Exception {
+ @Test
+ public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
+ processTestSubscribeToAttributesUpdates(true);
+ }
+ protected void processTestSubscribeToAttributesUpdates(boolean emptyCurrentStateNotification) throws Exception {
+ if (!emptyCurrentStateNotification) {
+ doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION, String.class, status().isOk());
+ }
CoapClient client = getCoapClient(FeatureType.ATTRIBUTES);
CountDownLatch latch = new CountDownLatch(1);
- TestCoapCallback testCoapCallback = new TestCoapCallback(latch);
+ TestCoapCallback callback = new TestCoapCallback(latch);
Request request = Request.newGet().setObserve();
request.setType(CoAP.Type.CON);
- CoapObserveRelation observeRelation = client.observe(request, testCoapCallback);
+ CoapObserveRelation observeRelation = client.observe(request, callback);
- Thread.sleep(1000);
+ latch.await(3, TimeUnit.SECONDS);
+
+ if (emptyCurrentStateNotification) {
+ validateEmptyCurrentStateAttributesResponse(callback);
+ } else {
+ validateCurrentStateAttributesResponse(callback);
+ }
+
+ latch = new CountDownLatch(1);
doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
latch.await(3, TimeUnit.SECONDS);
- validateUpdateAttributesResponse(testCoapCallback);
+ validateUpdateAttributesResponse(callback);
latch = new CountDownLatch(1);
doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
latch.await(3, TimeUnit.SECONDS);
- validateDeleteAttributesResponse(testCoapCallback);
+ validateDeleteAttributesResponse(callback);
observeRelation.proactiveCancel();
assertTrue(observeRelation.isCanceled());
}
- protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
+ protected void validateCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
+ assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(0, callback.getObserve().intValue());
+ String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
+ assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD_ON_CURRENT_STATE_NOTIFICATION), JacksonUtil.toJsonNode(response));
+ }
+
+ protected void validateEmptyCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
assertNotNull(callback.getPayloadBytes());
assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
assertEquals(0, callback.getObserve().intValue());
String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
+ assertEquals("{}", response);
+ }
+
+ protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
+ assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(1, callback.getObserve().intValue());
+ String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response));
}
protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
assertNotNull(callback.getPayloadBytes());
assertNotNull(callback.getObserve());
- assertEquals(1, callback.getObserve().intValue());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(2, callback.getObserve().intValue());
String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response));
}
@@ -110,13 +148,18 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
private Integer observe;
private byte[] payloadBytes;
+ private CoAP.ResponseCode responseCode;
+
+ public Integer getObserve() {
+ return observe;
+ }
public byte[] getPayloadBytes() {
return payloadBytes;
}
- public Integer getObserve() {
- return observe;
+ public CoAP.ResponseCode getResponseCode() {
+ return responseCode;
}
private TestCoapCallback(CountDownLatch latch) {
@@ -125,10 +168,9 @@ public abstract class AbstractCoapAttributesUpdatesIntegrationTest extends Abstr
@Override
public void onLoad(CoapResponse response) {
- assertNotNull(response.getPayload());
- assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT);
observe = response.getOptions().getObserve();
payloadBytes = response.getPayload();
+ responseCode = response.getCode();
latch.countDown();
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesJsonIntegrationTest.java
index adfef9fbef..24cc40f5c7 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesJsonIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesJsonIntegrationTest.java
@@ -39,4 +39,9 @@ public abstract class AbstractCoapAttributesUpdatesJsonIntegrationTest extends A
public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
super.testSubscribeToAttributesUpdatesFromTheServer();
}
+
+ @Test
+ public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
+ super.testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification();
+ }
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesProtoIntegrationTest.java
index 378354123e..625aaf1592 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesProtoIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/updates/AbstractCoapAttributesUpdatesProtoIntegrationTest.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.transport.coap.attributes.updates;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
+import org.eclipse.californium.core.coap.CoAP;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -24,11 +25,15 @@ import org.thingsboard.server.common.data.CoapDeviceType;
import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.gen.transport.TransportProtos;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@Slf4j
@@ -46,11 +51,54 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends
@Test
public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {
- processTestSubscribeToAttributesUpdates();
+ processTestSubscribeToAttributesUpdates(false);
+ }
+
+ @Test
+ public void testSubscribeToAttributesUpdatesFromTheServerWithEmptyCurrentStateNotification() throws Exception {
+ processTestSubscribeToAttributesUpdates(true);
+ }
+
+ protected void validateCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
+ assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(0, callback.getObserve().intValue());
+ TransportProtos.AttributeUpdateNotificationMsg.Builder expectedCurrentStateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
+ TransportProtos.TsKvProto tsKvProtoAttribute1 = getTsKvProto("attribute1", "value", TransportProtos.KeyValueType.STRING_V);
+ TransportProtos.TsKvProto tsKvProtoAttribute2 = getTsKvProto("attribute2", "false", TransportProtos.KeyValueType.BOOLEAN_V);
+ TransportProtos.TsKvProto tsKvProtoAttribute3 = getTsKvProto("attribute3", "41.0", TransportProtos.KeyValueType.DOUBLE_V);
+ TransportProtos.TsKvProto tsKvProtoAttribute4 = getTsKvProto("attribute4", "72", TransportProtos.KeyValueType.LONG_V);
+ TransportProtos.TsKvProto tsKvProtoAttribute5 = getTsKvProto("attribute5", "{\"someNumber\":41,\"someArray\":[],\"someNestedObject\":{\"key\":\"value\"}}", TransportProtos.KeyValueType.JSON_V);
+ List tsKvProtoList = new ArrayList<>();
+ tsKvProtoList.add(tsKvProtoAttribute1);
+ tsKvProtoList.add(tsKvProtoAttribute2);
+ tsKvProtoList.add(tsKvProtoAttribute3);
+ tsKvProtoList.add(tsKvProtoAttribute4);
+ tsKvProtoList.add(tsKvProtoAttribute5);
+ TransportProtos.AttributeUpdateNotificationMsg expectedCurrentStateNotificationMsg = expectedCurrentStateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList).build();
+ TransportProtos.AttributeUpdateNotificationMsg actualCurrentStateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
+
+ List expectedSharedUpdatedList = expectedCurrentStateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
+ List actualSharedUpdatedList = actualCurrentStateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
+
+ assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());
+ assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));
+
+ }
+
+ protected void validateEmptyCurrentStateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
+ assertNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(0, callback.getObserve().intValue());
}
protected void validateUpdateAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(1, callback.getObserve().intValue());
TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
List tsKvProtoList = getTsKvProtoList();
attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);
@@ -68,6 +116,9 @@ public abstract class AbstractCoapAttributesUpdatesProtoIntegrationTest extends
protected void validateDeleteAttributesResponse(TestCoapCallback callback) throws InvalidProtocolBufferException {
assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(2, callback.getObserve().intValue());
TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java
index a4210aa31a..3c47b2497e 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcDefaultIntegrationTest.java
@@ -83,7 +83,7 @@ public abstract class AbstractCoapServerSideRpcDefaultIntegrationTest extends Ab
@Test
public void testServerCoapTwoWayRpc() throws Exception {
- processTwoWayRpcTest();
+ processTwoWayRpcTest("{\"value1\":\"A\",\"value2\":\"B\"}");
}
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java
index d5d56db63b..a4dba5bb74 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.transport.coap.rpc;
+import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.californium.core.CoapClient;
@@ -24,17 +25,18 @@ import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.coap.Request;
-import org.junit.Assert;
-import org.thingsboard.server.transport.coap.AbstractCoapIntegrationTest;
+import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.CoapDeviceType;
import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.msg.session.FeatureType;
+import org.thingsboard.server.transport.coap.AbstractCoapIntegrationTest;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -55,57 +57,66 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
client.useCONs();
CountDownLatch latch = new CountDownLatch(1);
- TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, true);
+ TestCoapCallback callback = new TestCoapCallback(client, latch, true);
Request request = Request.newGet().setObserve();
- CoapObserveRelation observeRelation = client.observe(request, testCoapCallback);
+ CoapObserveRelation observeRelation = client.observe(request, callback);
+
+ latch.await(3, TimeUnit.SECONDS);
+
+ validateCurrentStateNotification(callback);
+
+ latch = new CountDownLatch(1);
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString();
String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk());
- Assert.assertTrue(StringUtils.isEmpty(result));
+
latch.await(3, TimeUnit.SECONDS);
- assertEquals(0, testCoapCallback.getObserve().intValue());
+
+ validateOneWayStateChangedNotification(callback, result);
+
observeRelation.proactiveCancel();
assertTrue(observeRelation.isCanceled());
}
- protected void processTwoWayRpcTest() throws Exception {
+ protected void processTwoWayRpcTest(String expectedResponseResult) throws Exception {
CoapClient client = getCoapClient(FeatureType.RPC);
client.useCONs();
CountDownLatch latch = new CountDownLatch(1);
- TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, false);
+ TestCoapCallback callback = new TestCoapCallback(client, latch, false);
Request request = Request.newGet().setObserve();
request.setType(CoAP.Type.CON);
- CoapObserveRelation observeRelation = client.observe(request, testCoapCallback);
+ CoapObserveRelation observeRelation = client.observe(request, callback);
+
+ latch.await(3, TimeUnit.SECONDS);
+
+ validateCurrentStateNotification(callback);
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString();
- String expected = "{\"value1\":\"A\",\"value2\":\"B\"}";
+ String actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
+ latch.await(3, TimeUnit.SECONDS);
+
+ validateTwoWayStateChangedNotification(callback, 1, expectedResponseResult, actualResult);
- String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
+ latch = new CountDownLatch(1);
+
+ actualResult = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
latch.await(3, TimeUnit.SECONDS);
- assertEquals(expected, result);
- assertEquals(0, testCoapCallback.getObserve().intValue());
+ validateTwoWayStateChangedNotification(callback, 2, expectedResponseResult, actualResult);
+
observeRelation.proactiveCancel();
assertTrue(observeRelation.isCanceled());
-
-// // TODO: 3/11/21 Fix test to validate next RPC
-// latch = new CountDownLatch(1);
-//
-// result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
-// latch.await(3, TimeUnit.SECONDS);
-//
-// assertEquals(expected, result);
-// assertEquals(1, testCoapCallback.getObserve().intValue());
}
protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) {
- client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe));
+ JsonNode responseJson = JacksonUtil.fromBytes(response.getPayload());
+ client.setURI(getRpcResponseFeatureTokenUrl(accessToken, responseJson.get("id").asInt()));
client.post(new CoapHandler() {
@Override
public void onLoad(CoapResponse response) {
@@ -130,11 +141,21 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
private final CountDownLatch latch;
private final boolean isOneWayRpc;
+ private Integer observe;
+ private byte[] payloadBytes;
+ private CoAP.ResponseCode responseCode;
+
public Integer getObserve() {
return observe;
}
- private Integer observe;
+ public byte[] getPayloadBytes() {
+ return payloadBytes;
+ }
+
+ public CoAP.ResponseCode getResponseCode() {
+ return responseCode;
+ }
TestCoapCallback(CoapClient client, CountDownLatch latch, boolean isOneWayRpc) {
this.client = client;
@@ -144,14 +165,15 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
@Override
public void onLoad(CoapResponse response) {
- log.warn("coap response: {}, {}", response.getResponseText(), response.getCode());
- assertNotNull(response.getPayload());
- assertEquals(response.getCode(), CoAP.ResponseCode.CONTENT);
+ payloadBytes = response.getPayload();
+ responseCode = response.getCode();
observe = response.getOptions().getObserve();
- if (!isOneWayRpc) {
- processOnLoadResponse(response, client, observe, latch);
- } else {
- latch.countDown();
+ if (observe != null) {
+ if (!isOneWayRpc && observe > 0) {
+ processOnLoadResponse(response, client, observe, latch);
+ } else {
+ latch.countDown();
+ }
}
}
@@ -162,4 +184,28 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC
}
+ private void validateCurrentStateNotification(TestCoapCallback callback) {
+ assertNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode.VALID);
+ assertEquals(0, callback.getObserve().intValue());
+ }
+
+ private void validateOneWayStateChangedNotification(TestCoapCallback callback, String result) {
+ assertTrue(StringUtils.isEmpty(result));
+ assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(1, callback.getObserve().intValue());
+ }
+
+ private void validateTwoWayStateChangedNotification(TestCoapCallback callback, int expectedObserveNumber, String expectedResult, String actualResult) {
+ assertEquals(expectedResult, actualResult);
+ assertNotNull(callback.getPayloadBytes());
+ assertNotNull(callback.getObserve());
+ assertEquals(callback.getResponseCode(), CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ assertEquals(expectedObserveNumber, callback.getObserve().intValue());
+ }
+
+
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcJsonIntegrationTest.java
index cecdb1fae0..3aa1dec074 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcJsonIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcJsonIntegrationTest.java
@@ -42,7 +42,7 @@ public abstract class AbstractCoapServerSideRpcJsonIntegrationTest extends Abstr
@Test
public void testServerCoapTwoWayRpc() throws Exception {
- processTwoWayRpcTest();
+ processTwoWayRpcTest("{\"value1\":\"A\",\"value2\":\"B\"}");
}
}
diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcProtoIntegrationTest.java
index 706a560024..544090d7c8 100644
--- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcProtoIntegrationTest.java
+++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcProtoIntegrationTest.java
@@ -85,37 +85,11 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst
@Test
public void testServerCoapTwoWayRpc() throws Exception {
- processTwoWayRpcTest();
- }
-
- protected void processTwoWayRpcTest() throws Exception {
- CoapClient client = getCoapClient(FeatureType.RPC);
- client.useCONs();
-
- CountDownLatch latch = new CountDownLatch(1);
- TestCoapCallback testCoapCallback = new TestCoapCallback(client, latch, false);
-
- Request request = Request.newGet().setObserve();
- request.setType(CoAP.Type.CON);
- CoapObserveRelation observeRelation = client.observe(request, testCoapCallback);
-
- String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";
- String deviceId = savedDevice.getId().getId().toString();
-
- String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}";
-
- String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
- latch.await(3, TimeUnit.SECONDS);
-
- assertEquals(expected, result);
- assertEquals(0, testCoapCallback.getObserve().intValue());
- observeRelation.proactiveCancel();
- assertTrue(observeRelation.isCanceled());
+ processTwoWayRpcTest("{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}");
}
@Override
protected void processOnLoadResponse(CoapResponse response, CoapClient client, Integer observe, CountDownLatch latch) {
- client.setURI(getRpcResponseFeatureTokenUrl(accessToken, observe));
ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration();
ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA);
DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA);
@@ -123,25 +97,22 @@ public abstract class AbstractCoapServerSideRpcProtoIntegrationTest extends Abst
byte[] requestPayload = response.getPayload();
DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg");
Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType();
- assertNotNull(rpcRequestMsgDescriptor);
try {
DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload);
- List fields = rpcRequestMsgDescriptor.getFields();
- for (Descriptors.FieldDescriptor fieldDescriptor: fields) {
- assertTrue(dynamicMessage.hasField(fieldDescriptor));
- }
+ Descriptors.FieldDescriptor requestIdDescriptor = rpcRequestMsgDescriptor.findFieldByName("requestId");
+ int requestId = (int) dynamicMessage.getField(requestIdDescriptor);
ProtoFileElement rpcResponseProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA);
DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcResponseProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA);
DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg");
Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType();
- assertNotNull(rpcResponseMsgDescriptor);
DynamicMessage rpcResponseMsg = rpcResponseBuilder
.setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE)
.build();
+ client.setURI(getRpcResponseFeatureTokenUrl(accessToken, requestId));
client.post(new CoapHandler() {
@Override
public void onLoad(CoapResponse response) {
- log.warn("Command Response Ack: {}, {}", response.getCode(), response.getResponseText());
+ log.warn("Command Response Ack: {}", response.getCode());
latch.countDown();
}
diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java
similarity index 80%
rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java
rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java
index 1acb09b28e..8b1f0804f3 100644
--- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/CaffeineFirmwareCache.java
+++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/CaffeineOtaPackageCache.java
@@ -13,19 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.cache.firmware;
+package org.thingsboard.server.cache.ota;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
-import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE;
+import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE;
+import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE;
@Service
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "caffeine", matchIfMissing = true)
@RequiredArgsConstructor
-public class CaffeineFirmwareCache implements FirmwareDataCache {
+public class CaffeineOtaPackageCache implements OtaPackageDataCache {
private final CacheManager cacheManager;
@@ -36,7 +37,7 @@ public class CaffeineFirmwareCache implements FirmwareDataCache {
@Override
public byte[] get(String key, int chunkSize, int chunk) {
- byte[] data = cacheManager.getCache(FIRMWARE_CACHE).get(key, byte[].class);
+ byte[] data = cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).get(key, byte[].class);
if (chunkSize < 1) {
return data;
@@ -58,11 +59,11 @@ public class CaffeineFirmwareCache implements FirmwareDataCache {
@Override
public void put(String key, byte[] value) {
- cacheManager.getCache(FIRMWARE_CACHE).putIfAbsent(key, value);
+ cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).putIfAbsent(key, value);
}
@Override
public void evict(String key) {
- cacheManager.getCache(FIRMWARE_CACHE).evict(key);
+ cacheManager.getCache(OTA_PACKAGE_DATA_CACHE).evict(key);
}
}
diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java
similarity index 82%
rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java
rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java
index 99f2f0d521..77057406c2 100644
--- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/FirmwareDataCache.java
+++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/OtaPackageDataCache.java
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.cache.firmware;
+package org.thingsboard.server.cache.ota;
-public interface FirmwareDataCache {
+public interface OtaPackageDataCache {
byte[] get(String key);
@@ -25,8 +25,8 @@ public interface FirmwareDataCache {
void evict(String key);
- default boolean has(String firmwareId) {
- byte[] data = get(firmwareId, 1, 0);
+ default boolean has(String otaPackageId) {
+ byte[] data = get(otaPackageId, 1, 0);
return data != null && data.length > 0;
}
}
diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java
similarity index 75%
rename from common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java
rename to common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java
index 08dd6facc2..c2c3bc34a8 100644
--- a/common/cache/src/main/java/org/thingsboard/server/cache/firmware/RedisFirmwareDataCache.java
+++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.cache.firmware;
+package org.thingsboard.server.cache.ota;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -21,12 +21,13 @@ import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Service;
-import static org.thingsboard.server.common.data.CacheConstants.FIRMWARE_CACHE;
+import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_CACHE;
+import static org.thingsboard.server.common.data.CacheConstants.OTA_PACKAGE_DATA_CACHE;
@Service
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@RequiredArgsConstructor
-public class RedisFirmwareDataCache implements FirmwareDataCache {
+public class RedisOtaPackageDataCache implements OtaPackageDataCache {
private final RedisConnectionFactory redisConnectionFactory;
@@ -39,30 +40,30 @@ public class RedisFirmwareDataCache implements FirmwareDataCache {
public byte[] get(String key, int chunkSize, int chunk) {
try (RedisConnection connection = redisConnectionFactory.getConnection()) {
if (chunkSize == 0) {
- return connection.get(toFirmwareCacheKey(key));
+ return connection.get(toOtaPackageCacheKey(key));
}
int startIndex = chunkSize * chunk;
int endIndex = startIndex + chunkSize - 1;
- return connection.getRange(toFirmwareCacheKey(key), startIndex, endIndex);
+ return connection.getRange(toOtaPackageCacheKey(key), startIndex, endIndex);
}
}
@Override
public void put(String key, byte[] value) {
try (RedisConnection connection = redisConnectionFactory.getConnection()) {
- connection.set(toFirmwareCacheKey(key), value);
+ connection.set(toOtaPackageCacheKey(key), value);
}
}
@Override
public void evict(String key) {
try (RedisConnection connection = redisConnectionFactory.getConnection()) {
- connection.del(toFirmwareCacheKey(key));
+ connection.del(toOtaPackageCacheKey(key));
}
}
- private byte[] toFirmwareCacheKey(String key) {
- return String.format("%s::%s", FIRMWARE_CACHE, key).getBytes();
+ private byte[] toOtaPackageCacheKey(String key) {
+ return String.format("%s::%s", OTA_PACKAGE_DATA_CACHE, key).getBytes();
}
}
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
index b4692ec5bf..761211f32c 100644
--- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
+++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
@@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.DeviceCredentials;
@@ -63,9 +64,9 @@ public interface DeviceService {
PageData findDevicesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
- PageData findDevicesByTenantIdAndTypeAndEmptyFirmware(TenantId tenantId, String type, PageLink pageLink);
+ PageData findDevicesByTenantIdAndTypeAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType type, PageLink pageLink);
- PageData findDevicesByTenantIdAndTypeAndEmptySoftware(TenantId tenantId, String type, PageLink pageLink);
+ Long countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType);
PageData findDeviceInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java
deleted file mode 100644
index eeaafbd777..0000000000
--- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright © 2016-2021 The Thingsboard Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.thingsboard.server.dao.firmware;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import org.thingsboard.server.common.data.Firmware;
-import org.thingsboard.server.common.data.FirmwareInfo;
-import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
-import org.thingsboard.server.common.data.id.TenantId;
-import org.thingsboard.server.common.data.page.PageData;
-import org.thingsboard.server.common.data.page.PageLink;
-
-import java.nio.ByteBuffer;
-
-public interface FirmwareService {
-
- FirmwareInfo saveFirmwareInfo(FirmwareInfo firmwareInfo);
-
- Firmware saveFirmware(Firmware firmware);
-
- String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data);
-
- Firmware findFirmwareById(TenantId tenantId, FirmwareId firmwareId);
-
- FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId);
-
- ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId);
-
- PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink);
-
- PageData findTenantFirmwaresByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, FirmwareType firmwareType, boolean hasData, PageLink pageLink);
-
- void deleteFirmware(TenantId tenantId, FirmwareId firmwareId);
-
- void deleteFirmwaresByTenantId(TenantId tenantId);
-}
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java
new file mode 100644
index 0000000000..589bdf14b6
--- /dev/null
+++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.ota;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.thingsboard.server.common.data.OtaPackage;
+import org.thingsboard.server.common.data.OtaPackageInfo;
+import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.id.DeviceProfileId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.page.PageData;
+import org.thingsboard.server.common.data.page.PageLink;
+
+import java.nio.ByteBuffer;
+
+public interface OtaPackageService {
+
+ OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo);
+
+ OtaPackage saveOtaPackage(OtaPackage otaPackage);
+
+ String generateChecksum(ChecksumAlgorithm checksumAlgorithm, ByteBuffer data);
+
+ OtaPackage findOtaPackageById(TenantId tenantId, OtaPackageId otaPackageId);
+
+ OtaPackageInfo findOtaPackageInfoById(TenantId tenantId, OtaPackageId otaPackageId);
+
+ ListenableFuture findOtaPackageInfoByIdAsync(TenantId tenantId, OtaPackageId otaPackageId);
+
+ PageData findTenantOtaPackagesByTenantId(TenantId tenantId, PageLink pageLink);
+
+ PageData findTenantOtaPackagesByTenantIdAndDeviceProfileIdAndTypeAndHasData(TenantId tenantId, DeviceProfileId deviceProfileId, OtaPackageType otaPackageType, boolean hasData, PageLink pageLink);
+
+ void deleteOtaPackage(TenantId tenantId, OtaPackageId otaPackageId);
+
+ void deleteOtaPackagesByTenantId(TenantId tenantId);
+}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
index ce4576705b..ced7a64a0f 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
@@ -29,5 +29,6 @@ public class CacheConstants {
public static final String DEVICE_PROFILE_CACHE = "deviceProfiles";
public static final String ATTRIBUTES_CACHE = "attributes";
public static final String TOKEN_OUTDATAGE_TIME_CACHE = "tokensOutdatageTime";
- public static final String FIRMWARE_CACHE = "firmwares";
+ public static final String OTA_PACKAGE_CACHE = "otaPackages";
+ public static final String OTA_PACKAGE_DATA_CACHE = "otaPackagesData";
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
index 62459fc0ad..002cbbb733 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
@@ -66,6 +66,7 @@ public class DataConstants {
public static final String TIMESERIES_DELETED = "TIMESERIES_DELETED";
public static final String ALARM_ACK = "ALARM_ACK";
public static final String ALARM_CLEAR = "ALARM_CLEAR";
+ public static final String ALARM_DELETE = "ALARM_DELETE";
public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT";
public static final String ENTITY_ASSIGNED_TO_TENANT = "ENTITY_ASSIGNED_TO_TENANT";
public static final String PROVISION_SUCCESS = "PROVISION_SUCCESS";
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java
index bce3ba703f..9abc619b48 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.validation.NoXss;
@@ -32,7 +32,7 @@ import java.io.IOException;
@EqualsAndHashCode(callSuper = true)
@Slf4j
-public class Device extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, HasFirmware {
+public class Device extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, HasOtaPackage {
private static final long serialVersionUID = 2807343040519543363L;
@@ -49,8 +49,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen
@JsonIgnore
private byte[] deviceDataBytes;
- private FirmwareId firmwareId;
- private FirmwareId softwareId;
+ private OtaPackageId firmwareId;
+ private OtaPackageId softwareId;
public Device() {
super();
@@ -167,19 +167,19 @@ public class Device extends SearchTextBasedWithAdditionalInfo implemen
return getName();
}
- public FirmwareId getFirmwareId() {
+ public OtaPackageId getFirmwareId() {
return firmwareId;
}
- public void setFirmwareId(FirmwareId firmwareId) {
+ public void setFirmwareId(OtaPackageId firmwareId) {
this.firmwareId = firmwareId;
}
- public FirmwareId getSoftwareId() {
+ public OtaPackageId getSoftwareId() {
return softwareId;
}
- public void setSoftwareId(FirmwareId softwareId) {
+ public void setSoftwareId(OtaPackageId softwareId) {
this.softwareId = softwareId;
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java
index e35fbb84a0..13c4692976 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java
@@ -23,7 +23,7 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.validation.NoXss;
@@ -37,7 +37,7 @@ import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalIn
@Data
@EqualsAndHashCode(callSuper = true)
@Slf4j
-public class DeviceProfile extends SearchTextBased implements HasName, HasTenantId, HasFirmware {
+public class DeviceProfile extends SearchTextBased implements HasName, HasTenantId, HasOtaPackage {
private TenantId tenantId;
@NoXss
@@ -60,9 +60,9 @@ public class DeviceProfile extends SearchTextBased implements H
@NoXss
private String provisionDeviceKey;
- private FirmwareId firmwareId;
+ private OtaPackageId firmwareId;
- private FirmwareId softwareId;
+ private OtaPackageId softwareId;
public DeviceProfile() {
super();
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
index d3508d42dd..cf6c6fd9a7 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
* @author Andrew Shvayka
*/
public enum EntityType {
- 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;
+ 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;
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java b/common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java
similarity index 80%
rename from common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java
index ae05829092..09320e13d0 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/HasFirmware.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/HasOtaPackage.java
@@ -15,11 +15,11 @@
*/
package org.thingsboard.server.common.data;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
-public interface HasFirmware {
+public interface HasOtaPackage {
- FirmwareId getFirmwareId();
+ OtaPackageId getFirmwareId();
- FirmwareId getSoftwareId();
+ OtaPackageId getSoftwareId();
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java
similarity index 82%
rename from common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java
index b4155a578a..6110310cd3 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/Firmware.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java
@@ -17,27 +17,27 @@ package org.thingsboard.server.common.data;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import java.nio.ByteBuffer;
@Data
@EqualsAndHashCode(callSuper = true)
-public class Firmware extends FirmwareInfo {
+public class OtaPackage extends OtaPackageInfo {
private static final long serialVersionUID = 3091601761339422546L;
private transient ByteBuffer data;
- public Firmware() {
+ public OtaPackage() {
super();
}
- public Firmware(FirmwareId id) {
+ public OtaPackage(OtaPackageId id) {
super(id);
}
- public Firmware(Firmware firmware) {
+ public OtaPackage(OtaPackage firmware) {
super(firmware);
this.data = firmware.getData();
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java
similarity index 58%
rename from common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java
index 33b529e303..5a33a95215 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java
@@ -19,22 +19,22 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
-import org.thingsboard.server.common.data.firmware.ChecksumAlgorithm;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.ChecksumAlgorithm;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
-public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId {
+public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId {
private static final long serialVersionUID = 3168391583570815419L;
private TenantId tenantId;
private DeviceProfileId deviceProfileId;
- private FirmwareType type;
+ private OtaPackageType type;
private String title;
private String version;
private boolean hasData;
@@ -45,27 +45,27 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo
private Long dataSize;
- public FirmwareInfo() {
+ public OtaPackageInfo() {
super();
}
- public FirmwareInfo(FirmwareId id) {
+ public OtaPackageInfo(OtaPackageId id) {
super(id);
}
- public FirmwareInfo(FirmwareInfo firmwareInfo) {
- super(firmwareInfo);
- this.tenantId = firmwareInfo.getTenantId();
- this.deviceProfileId = firmwareInfo.getDeviceProfileId();
- this.type = firmwareInfo.getType();
- this.title = firmwareInfo.getTitle();
- this.version = firmwareInfo.getVersion();
- this.hasData = firmwareInfo.isHasData();
- this.fileName = firmwareInfo.getFileName();
- this.contentType = firmwareInfo.getContentType();
- this.checksumAlgorithm = firmwareInfo.getChecksumAlgorithm();
- this.checksum = firmwareInfo.getChecksum();
- this.dataSize = firmwareInfo.getDataSize();
+ public OtaPackageInfo(OtaPackageInfo otaPackageInfo) {
+ super(otaPackageInfo);
+ this.tenantId = otaPackageInfo.getTenantId();
+ this.deviceProfileId = otaPackageInfo.getDeviceProfileId();
+ this.type = otaPackageInfo.getType();
+ this.title = otaPackageInfo.getTitle();
+ this.version = otaPackageInfo.getVersion();
+ this.hasData = otaPackageInfo.isHasData();
+ this.fileName = otaPackageInfo.getFileName();
+ this.contentType = otaPackageInfo.getContentType();
+ this.checksumAlgorithm = otaPackageInfo.getChecksumAlgorithm();
+ this.checksum = otaPackageInfo.getChecksum();
+ this.dataSize = otaPackageInfo.getDataSize();
}
@Override
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java
index a0fefea6cc..05d22af09f 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java
@@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.Optional;
import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.mapper;
@@ -92,6 +93,13 @@ public class TenantProfile extends SearchTextBased implements H
}
}
+ @JsonIgnore
+ public Optional getProfileConfiguration() {
+ return Optional.ofNullable(getProfileData().getConfiguration())
+ .filter(profileConfiguration -> profileConfiguration instanceof DefaultTenantProfileConfiguration)
+ .map(profileConfiguration -> (DefaultTenantProfileConfiguration) profileConfiguration);
+ }
+
public TenantProfileData createDefaultTenantProfileData() {
TenantProfileData tpd = new TenantProfileData();
tpd.setConfiguration(new DefaultTenantProfileConfiguration());
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
index 2594c73ebe..489c45f68d 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
@@ -39,6 +39,7 @@ public enum ActionType {
RELATIONS_DELETED(false),
ALARM_ACK(false),
ALARM_CLEAR(false),
+ ALARM_DELETE(false),
LOGIN(false),
LOGOUT(false),
LOCKOUT(false),
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/exception/ApiUsageLimitsExceededException.java b/common/data/src/main/java/org/thingsboard/server/common/data/exception/ApiUsageLimitsExceededException.java
new file mode 100644
index 0000000000..fb5c4dffeb
--- /dev/null
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/exception/ApiUsageLimitsExceededException.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.common.data.exception;
+
+public class ApiUsageLimitsExceededException extends RuntimeException {
+ public ApiUsageLimitsExceededException(String message) {
+ super(message);
+ }
+
+ public ApiUsageLimitsExceededException() {
+ }
+}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
index df2846eead..a4b2327c75 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
@@ -71,8 +71,8 @@ public class EntityIdFactory {
return new ApiUsageStateId(uuid);
case TB_RESOURCE:
return new TbResourceId(uuid);
- case FIRMWARE:
- return new FirmwareId(uuid);
+ case OTA_PACKAGE:
+ return new OtaPackageId(uuid);
case EDGE:
return new EdgeId(uuid);
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java
similarity index 79%
rename from common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java
index 3cdee53f58..0442792238 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/id/FirmwareId.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java
@@ -22,23 +22,23 @@ import org.thingsboard.server.common.data.EntityType;
import java.util.UUID;
-public class FirmwareId extends UUIDBased implements EntityId {
+public class OtaPackageId extends UUIDBased implements EntityId {
private static final long serialVersionUID = 1L;
@JsonCreator
- public FirmwareId(@JsonProperty("id") UUID id) {
+ public OtaPackageId(@JsonProperty("id") UUID id) {
super(id);
}
- public static FirmwareId fromString(String firmwareId) {
- return new FirmwareId(UUID.fromString(firmwareId));
+ public static OtaPackageId fromString(String firmwareId) {
+ return new OtaPackageId(UUID.fromString(firmwareId));
}
@JsonIgnore
@Override
public EntityType getEntityType() {
- return EntityType.FIRMWARE;
+ return EntityType.OTA_PACKAGE;
}
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java
similarity index 93%
rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java
index 3998482e35..ce33463054 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/ChecksumAlgorithm.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/ChecksumAlgorithm.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.common.data.firmware;
+package org.thingsboard.server.common.data.ota;
public enum ChecksumAlgorithm {
MD5,
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java
similarity index 88%
rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java
index cb38b6724c..0528b9dfe3 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareKey.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageKey.java
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.common.data.firmware;
+package org.thingsboard.server.common.data.ota;
import lombok.Getter;
-public enum FirmwareKey {
+public enum OtaPackageKey {
TITLE("title"), VERSION("version"), TS("ts"), STATE("state"), SIZE("size"), CHECKSUM("checksum"), CHECKSUM_ALGORITHM("checksum_algorithm");
@Getter
private final String value;
- FirmwareKey(String value) {
+ OtaPackageKey(String value) {
this.value = value;
}
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java
similarity index 86%
rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java
index 5f6aa0d925..cab8cf1847 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareType.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageType.java
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.common.data.firmware;
+package org.thingsboard.server.common.data.ota;
import lombok.Getter;
-public enum FirmwareType {
+public enum OtaPackageType {
FIRMWARE("fw"), SOFTWARE("sw");
@Getter
private final String keyPrefix;
- FirmwareType(String keyPrefix) {
+ OtaPackageType(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java
similarity index 88%
rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java
index 3e46174792..caa043c595 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUpdateStatus.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUpdateStatus.java
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.common.data.firmware;
+package org.thingsboard.server.common.data.ota;
-public enum FirmwareUpdateStatus {
+public enum OtaPackageUpdateStatus {
QUEUED, INITIATED, DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java
similarity index 52%
rename from common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java
rename to common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java
index 646ad24173..f2b29ec1f2 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/firmware/FirmwareUtil.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ota/OtaPackageUtil.java
@@ -13,21 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.thingsboard.server.common.data.firmware;
+package org.thingsboard.server.common.data.ota;
import lombok.extern.slf4j.Slf4j;
-import org.thingsboard.server.common.data.HasFirmware;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.HasOtaPackage;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-
-import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE;
+import java.util.function.Supplier;
@Slf4j
-public class FirmwareUtil {
+public class OtaPackageUtil {
public static final List ALL_FW_ATTRIBUTE_KEYS;
@@ -35,19 +33,19 @@ public class FirmwareUtil {
static {
ALL_FW_ATTRIBUTE_KEYS = new ArrayList<>();
- for (FirmwareKey key : FirmwareKey.values()) {
- ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(FIRMWARE, key));
+ for (OtaPackageKey key : OtaPackageKey.values()) {
+ ALL_FW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.FIRMWARE, key));
}
ALL_SW_ATTRIBUTE_KEYS = new ArrayList<>();
- for (FirmwareKey key : FirmwareKey.values()) {
- ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(SOFTWARE, key));
+ for (OtaPackageKey key : OtaPackageKey.values()) {
+ ALL_SW_ATTRIBUTE_KEYS.add(getAttributeKey(OtaPackageType.SOFTWARE, key));
}
}
- public static List getAttributeKeys(FirmwareType firmwareType) {
+ public static List getAttributeKeys(OtaPackageType firmwareType) {
switch (firmwareType) {
case FIRMWARE:
return ALL_FW_ATTRIBUTE_KEYS;
@@ -57,35 +55,46 @@ public class FirmwareUtil {
return Collections.emptyList();
}
- public static String getAttributeKey(FirmwareType type, FirmwareKey key) {
+ public static String getAttributeKey(OtaPackageType type, OtaPackageKey key) {
return type.getKeyPrefix() + "_" + key.getValue();
}
- public static String getTargetTelemetryKey(FirmwareType type, FirmwareKey key) {
+ public static String getTargetTelemetryKey(OtaPackageType type, OtaPackageKey key) {
return getTelemetryKey("target_", type, key);
}
- public static String getCurrentTelemetryKey(FirmwareType type, FirmwareKey key) {
+ public static String getCurrentTelemetryKey(OtaPackageType type, OtaPackageKey key) {
return getTelemetryKey("current_", type, key);
}
- private static String getTelemetryKey(String prefix, FirmwareType type, FirmwareKey key) {
+ private static String getTelemetryKey(String prefix, OtaPackageType type, OtaPackageKey key) {
return prefix + type.getKeyPrefix() + "_" + key.getValue();
}
- public static String getTelemetryKey(FirmwareType type, FirmwareKey key) {
+ public static String getTelemetryKey(OtaPackageType type, OtaPackageKey key) {
return type.getKeyPrefix() + "_" + key.getValue();
}
- public static FirmwareId getFirmwareId(HasFirmware entity, FirmwareType firmwareType) {
- switch (firmwareType) {
+ public static OtaPackageId getOtaPackageId(HasOtaPackage entity, OtaPackageType type) {
+ switch (type) {
case FIRMWARE:
return entity.getFirmwareId();
case SOFTWARE:
return entity.getSoftwareId();
default:
- log.warn("Unsupported firmware type: [{}]", firmwareType);
+ log.warn("Unsupported ota package type: [{}]", type);
return null;
}
}
+
+ public static T getByOtaPackageType(Supplier firmwareSupplier, Supplier softwareSupplier, OtaPackageType type) {
+ switch (type) {
+ case FIRMWARE:
+ return firmwareSupplier.get();
+ case SOFTWARE:
+ return softwareSupplier.get();
+ default:
+ throw new RuntimeException("Unsupported OtaPackage type: " + type);
+ }
+ }
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java
index 2020245ea1..6ffbce4d3d 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java
@@ -17,10 +17,11 @@ package org.thingsboard.server.common.data.page;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.thingsboard.server.common.data.BaseData;
import java.util.Collections;
import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class PageData {
@@ -61,4 +62,8 @@ public class PageData {
return hasNext;
}
+ public PageData mapData(Function mapper) {
+ return new PageData<>(getData().stream().map(mapper).collect(Collectors.toList()), getTotalPages(), getTotalElements(), hasNext());
+ }
+
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
index b9bd72b0db..34f0b38ebf 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
@@ -53,6 +53,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
private long maxCreatedAlarms;
private int defaultStorageTtlDays;
+ private int alarmsTtlDays;
private double warnThreshold;
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java
index 1a6a1a56e4..624918c8dd 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java
@@ -38,7 +38,7 @@ public class TbKafkaTopicConfigs {
private String notificationsProperties;
@Value("${queue.kafka.topic-properties.js-executor}")
private String jsExecutorProperties;
- @Value("${queue.kafka.topic-properties.fw-updates:}")
+ @Value("${queue.kafka.topic-properties.ota-updates:}")
private String fwUpdatesProperties;
@Getter
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java
index c2f4f4f750..d89b03c744 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java
@@ -187,14 +187,14 @@ public class AwsSqsMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic());
}
@PreDestroy
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java
index 0267cdecb8..eaa73bc108 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -177,14 +177,14 @@ public class AwsSqsTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbAwsSqsConsumerTemplate<>(transportApiAdmin, sqsSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getOtaPackageTopic());
}
@PreDestroy
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java
index 8806176f9f..cd1c34b612 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java
@@ -131,13 +131,13 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new InMemoryTbQueueConsumer<>(coreSettings.getFirmwareTopic());
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new InMemoryTbQueueConsumer<>(coreSettings.getOtaPackageTopic());
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new InMemoryTbQueueProducer<>(coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new InMemoryTbQueueProducer<>(coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java
index a526331116..c57260bef8 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -277,24 +277,24 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder();
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder();
consumerBuilder.settings(kafkaSettings);
- consumerBuilder.topic(coreSettings.getFirmwareTopic());
- consumerBuilder.clientId("monolith-fw-consumer-" + serviceInfoProvider.getServiceId());
- consumerBuilder.groupId("monolith-fw-consumer");
- consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ consumerBuilder.topic(coreSettings.getOtaPackageTopic());
+ consumerBuilder.clientId("monolith-ota-consumer-" + serviceInfoProvider.getServiceId());
+ consumerBuilder.groupId("monolith-ota-consumer");
+ consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
consumerBuilder.admin(fwUpdatesAdmin);
consumerBuilder.statsService(consumerStatsService);
return consumerBuilder.build();
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder();
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder();
requestBuilder.settings(kafkaSettings);
- requestBuilder.clientId("monolith-fw-producer-" + serviceInfoProvider.getServiceId());
- requestBuilder.defaultTopic(coreSettings.getFirmwareTopic());
+ requestBuilder.clientId("monolith-ota-producer-" + serviceInfoProvider.getServiceId());
+ requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic());
requestBuilder.admin(fwUpdatesAdmin);
return requestBuilder.build();
}
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java
index 5f64e42ffd..bec01c7201 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -245,24 +245,24 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder();
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> consumerBuilder = TbKafkaConsumerTemplate.builder();
consumerBuilder.settings(kafkaSettings);
- consumerBuilder.topic(coreSettings.getFirmwareTopic());
- consumerBuilder.clientId("tb-core-fw-consumer-" + serviceInfoProvider.getServiceId());
- consumerBuilder.groupId("tb-core-fw-consumer");
- consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ consumerBuilder.topic(coreSettings.getOtaPackageTopic());
+ consumerBuilder.clientId("tb-core-ota-consumer-" + serviceInfoProvider.getServiceId());
+ consumerBuilder.groupId("tb-core-ota-consumer");
+ consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
consumerBuilder.admin(fwUpdatesAdmin);
consumerBuilder.statsService(consumerStatsService);
return consumerBuilder.build();
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder();
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder();
requestBuilder.settings(kafkaSettings);
- requestBuilder.clientId("tb-core-fw-producer-" + serviceInfoProvider.getServiceId());
- requestBuilder.defaultTopic(coreSettings.getFirmwareTopic());
+ requestBuilder.clientId("tb-core-ota-producer-" + serviceInfoProvider.getServiceId());
+ requestBuilder.defaultTopic(coreSettings.getOtaPackageTopic());
requestBuilder.admin(fwUpdatesAdmin);
return requestBuilder.build();
}
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java
index 3504c6aef2..3f014f578c 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java
@@ -22,9 +22,9 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
-import org.thingsboard.server.gen.transport.TransportProtos.*;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -192,14 +192,14 @@ public class PubSubMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEng
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java
index a9ebf5a4de..65ea183d66 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -166,14 +166,14 @@ public class PubSubTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbPubSubConsumerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java
index cd6043cdde..7730f8f5dd 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java
@@ -24,7 +24,7 @@ import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsRequest;
import org.thingsboard.server.gen.js.JsInvokeProtos.RemoteJsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -190,14 +190,14 @@ public class RabbitMqMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java
index 8b5ad00de4..c0abeab162 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -172,14 +172,14 @@ public class RabbitMqTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbRabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java
index b569d13742..2443093cf0 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -189,14 +189,14 @@ public class ServiceBusMonolithQueueFactory implements TbCoreQueueFactory, TbRul
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java
index 17e6eb9a27..7a9da236ed 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
@@ -172,14 +172,14 @@ public class ServiceBusTbCoreQueueFactory implements TbCoreQueueFactory {
}
@Override
- public TbQueueConsumer> createToFirmwareStateServiceMsgConsumer() {
- return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic(),
- msg -> new TbProtoQueueMsg<>(msg.getKey(), ToFirmwareStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
+ public TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer() {
+ return new TbServiceBusConsumerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic(),
+ msg -> new TbProtoQueueMsg<>(msg.getKey(), ToOtaPackageStateServiceMsg.parseFrom(msg.getData()), msg.getHeaders()));
}
@Override
- public TbQueueProducer> createToFirmwareStateServiceMsgProducer() {
- return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getFirmwareTopic());
+ public TbQueueProducer> createToOtaPackageStateServiceMsgProducer() {
+ return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getOtaPackageTopic());
}
@Override
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java
index be5ca967bf..584a6e389b 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueFactory.java
@@ -16,7 +16,7 @@
package org.thingsboard.server.queue.provider;
import org.thingsboard.server.gen.js.JsInvokeProtos;
-import org.thingsboard.server.gen.transport.TransportProtos.ToFirmwareStateServiceMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateServiceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
@@ -91,14 +91,14 @@ public interface TbCoreQueueFactory extends TbUsageStatsClientQueueFactory {
*
* @return
*/
- TbQueueConsumer> createToFirmwareStateServiceMsgConsumer();
+ TbQueueConsumer> createToOtaPackageStateServiceMsgConsumer();
/**
* Used to consume messages about firmware update notifications by TB Core Service
*
* @return
*/
- TbQueueProducer> createToFirmwareStateServiceMsgProducer();
+ TbQueueProducer> createToOtaPackageStateServiceMsgProducer();
/**
* Used to consume high priority messages by TB Core Service
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java
index b7e7a155ed..6c8ab4455b 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java
@@ -15,7 +15,6 @@
*/
package org.thingsboard.server.queue.provider;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
@@ -25,11 +24,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
+import org.thingsboard.server.queue.util.TbCoreComponent;
import javax.annotation.PostConstruct;
@Service
-@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
+@TbCoreComponent
public class TbCoreQueueProducerProvider implements TbQueueProducerProvider {
private final TbCoreQueueFactory tbQueueProvider;
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java
index d194fdb4ea..3c9ff5813e 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java
@@ -26,8 +26,8 @@ public class TbQueueCoreSettings {
@Value("${queue.core.topic}")
private String topic;
- @Value("${queue.core.firmware.topic:tb_firmware}")
- private String firmwareTopic;
+ @Value("${queue.core.ota.topic:tb_ota_package}")
+ private String otaPackageTopic;
@Value("${queue.core.usage-stats-topic:tb_usage_stats}")
private String usageStatsTopic;
diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto
index 74363ed814..faf88c5620 100644
--- a/common/queue/src/main/proto/queue.proto
+++ b/common/queue/src/main/proto/queue.proto
@@ -137,6 +137,7 @@ message GetAttributeRequestMsg {
int32 requestId = 1;
repeated string clientAttributeNames = 2;
repeated string sharedAttributeNames = 3;
+ bool onlyShared = 4;
}
message GetAttributeResponseMsg {
@@ -144,6 +145,7 @@ message GetAttributeResponseMsg {
repeated TsKvProto clientAttributeList = 2;
repeated TsKvProto sharedAttributeList = 3;
string error = 5;
+ bool sharedStateMsg = 6;
}
message AttributeUpdateNotificationMsg {
@@ -386,7 +388,7 @@ enum ResponseStatus {
FAILURE = 3;
}
-message GetFirmwareRequestMsg {
+message GetOtaPackageRequestMsg {
int64 deviceIdMSB = 1;
int64 deviceIdLSB = 2;
int64 tenantIdMSB = 3;
@@ -394,10 +396,10 @@ message GetFirmwareRequestMsg {
string type = 5;
}
-message GetFirmwareResponseMsg {
+message GetOtaPackageResponseMsg {
ResponseStatus responseStatus = 1;
- int64 firmwareIdMSB = 2;
- int64 firmwareIdLSB = 3;
+ int64 otaPackageIdMSB = 2;
+ int64 otaPackageIdLSB = 3;
string type = 4;
string title = 5;
string version = 6;
@@ -625,7 +627,7 @@ message TransportApiRequestMsg {
ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7;
ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8;
GetResourceRequestMsg resourceRequestMsg = 9;
- GetFirmwareRequestMsg firmwareRequestMsg = 10;
+ GetOtaPackageRequestMsg otaPackageRequestMsg = 10;
GetSnmpDevicesRequestMsg snmpDevicesRequestMsg = 11;
GetDeviceRequestMsg deviceRequestMsg = 12;
GetDeviceCredentialsRequestMsg deviceCredentialsRequestMsg = 13;
@@ -640,7 +642,7 @@ message TransportApiResponseMsg {
GetSnmpDevicesResponseMsg snmpDevicesResponseMsg = 5;
LwM2MResponseMsg lwM2MResponseMsg = 6;
GetResourceResponseMsg resourceResponseMsg = 7;
- GetFirmwareResponseMsg firmwareResponseMsg = 8;
+ GetOtaPackageResponseMsg otaPackageResponseMsg = 8;
GetDeviceResponseMsg deviceResponseMsg = 9;
GetDeviceCredentialsResponseMsg deviceCredentialsResponseMsg = 10;
}
@@ -708,13 +710,13 @@ message ToUsageStatsServiceMsg {
int64 customerIdLSB = 7;
}
-message ToFirmwareStateServiceMsg {
+message ToOtaPackageStateServiceMsg {
int64 ts = 1;
int64 tenantIdMSB = 2;
int64 tenantIdLSB = 3;
int64 deviceIdMSB = 4;
int64 deviceIdLSB = 5;
- int64 firmwareIdMSB = 6;
- int64 firmwareIdLSB = 7;
+ int64 otaPackageIdMSB = 6;
+ int64 otaPackageIdLSB = 7;
string type = 8;
}
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/AbstractCoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/AbstractCoapTransportResource.java
index 85a4f5ba70..7ab1306953 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/AbstractCoapTransportResource.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/AbstractCoapTransportResource.java
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP;
+import org.eclipse.californium.core.coap.Response;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.transport.TransportContext;
@@ -56,7 +57,7 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
protected abstract void processHandlePost(CoapExchange exchange);
- protected void reportActivity(TransportProtos.SessionInfoProto sessionInfo, boolean hasAttributeSubscription, boolean hasRpcSubscription) {
+ protected void reportSubscriptionInfo(TransportProtos.SessionInfoProto sessionInfo, boolean hasAttributeSubscription, boolean hasRpcSubscription) {
transportContext.getTransportService().process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder()
.setAttributeSubscription(hasAttributeSubscription)
.setRpcSubscription(hasRpcSubscription)
@@ -64,6 +65,10 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
.build(), TransportServiceCallback.EMPTY);
}
+ protected void reportActivity(TransportProtos.SessionInfoProto sessionInfo) {
+ transportService.reportActivity(sessionInfo);
+ }
+
protected static TransportProtos.SessionEventMsg getSessionEventMsg(TransportProtos.SessionEvent event) {
return TransportProtos.SessionEventMsg.newBuilder()
.setSessionType(TransportProtos.SessionType.ASYNC)
@@ -112,13 +117,19 @@ public abstract class AbstractCoapTransportResource extends CoapResource {
@Override
public void onSuccess(Void msg) {
- exchange.respond(onSuccessResponse);
+ Response response = new Response(onSuccessResponse);
+ response.setAcknowledged(isConRequest());
+ exchange.respond(response);
}
@Override
public void onError(Throwable e) {
exchange.respond(onFailureResponse);
}
+
+ private boolean isConRequest() {
+ return exchange.advanced().getRequest().isConfirmable();
+ }
}
public static class CoapNoOpCallback implements TransportServiceCallback {
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java
index 9133809225..6dc0b6540a 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.coap;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
@@ -34,6 +35,10 @@ import org.thingsboard.server.transport.coap.efento.adaptor.EfentoCoapAdaptor;
@Component
public class CoapTransportContext extends TransportContext {
+ @Getter
+ @Value("${transport.sessions.report_timeout}")
+ private long sessionReportTimeout;
+
@Getter
@Autowired
private JsonCoapAdaptor jsonCoapAdaptor;
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
index e287a28aa0..cd80aa42df 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
@@ -28,6 +28,7 @@ import org.eclipse.californium.core.observe.ObserveRelation;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.core.server.resources.Resource;
import org.eclipse.californium.core.server.resources.ResourceObserver;
+import org.springframework.util.CollectionUtils;
import org.thingsboard.server.coapserver.CoapServerService;
import org.thingsboard.server.coapserver.TbCoapDtlsSessionInfo;
import org.thingsboard.server.common.data.DataConstants;
@@ -43,7 +44,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC
import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.security.DeviceTokenCredentials;
import org.thingsboard.server.common.msg.session.FeatureType;
import org.thingsboard.server.common.msg.session.SessionMsgType;
@@ -55,11 +56,14 @@ import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@@ -72,25 +76,30 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
private static final int REQUEST_ID_POSITION_CERTIFICATE_REQUEST = 4;
private static final String DTLS_SESSION_ID_KEY = "DTLS_SESSION_ID";
- private final ConcurrentMap tokenToSessionIdMap = new ConcurrentHashMap<>();
- private final ConcurrentMap tokenToNotificationCounterMap = new ConcurrentHashMap<>();
+ private final ConcurrentMap tokenToSessionInfoMap = new ConcurrentHashMap<>();
+ private final ConcurrentMap tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>();
+ private final ConcurrentMap sessionInfoToObserveRelationMap = new ConcurrentHashMap<>();
private final Set rpcSubscriptions = ConcurrentHashMap.newKeySet();
private final Set attributeSubscriptions = ConcurrentHashMap.newKeySet();
private ConcurrentMap dtlsSessionIdMap;
private long timeout;
+ private long sessionReportTimeout;
- public CoapTransportResource(CoapTransportContext coapTransportContext, CoapServerService coapServerService, String name) {
- super(coapTransportContext, name);
+ public CoapTransportResource(CoapTransportContext ctx, CoapServerService coapServerService, String name) {
+ super(ctx, name);
this.setObservable(true); // enable observing
this.addObserver(new CoapResourceObserver());
this.dtlsSessionIdMap = coapServerService.getDtlsSessionsMap();
this.timeout = coapServerService.getTimeout();
-// this.setObservable(false); // disable observing
-// this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
-// this.getAttributes().setObservable(); // mark observable in the Link-Format
+ this.sessionReportTimeout = ctx.getSessionReportTimeout();
+ ctx.getScheduler().scheduleAtFixedRate(() -> {
+ Set observeSessions = sessionInfoToObserveRelationMap.keySet();
+ observeSessions.forEach(this::reportActivity);
+ }, new Random().nextInt((int) sessionReportTimeout), sessionReportTimeout, TimeUnit.MILLISECONDS);
}
+ @Override
public void checkObserveRelation(Exchange exchange, Response response) {
String token = getTokenFromRequest(exchange.getRequest());
final ObserveRelation relation = exchange.getRelation();
@@ -103,11 +112,20 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
relation.setEstablished();
addObserveRelation(relation);
}
- AtomicInteger notificationCounter = tokenToNotificationCounterMap.computeIfAbsent(token, s -> new AtomicInteger(0));
+ AtomicInteger notificationCounter = tokenToObserveNotificationSeqMap.computeIfAbsent(token, s -> new AtomicInteger(0));
response.getOptions().setObserve(notificationCounter.getAndIncrement());
} // ObserveLayer takes care of the else case
}
+ public void clearAndNotifyObserveRelation(ObserveRelation relation, CoAP.ResponseCode code) {
+ relation.cancel();
+ relation.getExchange().sendResponse(new Response(code));
+ }
+
+ public Map getSessionInfoToObserveRelationMap() {
+ return sessionInfoToObserveRelationMap;
+ }
+
@Override
protected void processHandleGet(CoapExchange exchange) {
Optional featureType = getFeatureType(exchange.advanced().getRequest());
@@ -239,7 +257,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
}
private void processRequest(CoapExchange exchange, SessionMsgType type, Request request, TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
- UUID sessionId = new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB());
+ UUID sessionId = toSessionId(sessionInfo);
try {
TransportConfigurationContainer transportConfigurationContainer = getTransportConfigurationContainer(deviceProfile);
CoapTransportAdaptor coapTransportAdaptor = getCoapTransportAdaptor(transportConfigurationContainer.isJsonPayload());
@@ -249,14 +267,14 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
coapTransportAdaptor.convertToPostAttributes(sessionId, request,
transportConfigurationContainer.getAttributesMsgDescriptor()),
new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
- reportActivity(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
+ reportSubscriptionInfo(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
break;
case POST_TELEMETRY_REQUEST:
transportService.process(sessionInfo,
coapTransportAdaptor.convertToPostTelemetry(sessionId, request,
transportConfigurationContainer.getTelemetryMsgDescriptor()),
new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
- reportActivity(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
+ reportSubscriptionInfo(sessionInfo, attributeSubscriptions.contains(sessionId), rpcSubscriptions.contains(sessionId));
break;
case CLAIM_REQUEST:
transportService.process(sessionInfo,
@@ -264,49 +282,52 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
break;
case SUBSCRIBE_ATTRIBUTES_REQUEST:
- TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionIdMap.get(getTokenFromRequest(request));
+ TransportProtos.SessionInfoProto currentAttrSession = tokenToSessionInfoMap.get(getTokenFromRequest(request));
if (currentAttrSession == null) {
attributeSubscriptions.add(sessionId);
registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor,
transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request));
transportService.process(sessionInfo,
TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), new CoapNoOpCallback(exchange));
+ transportService.process(sessionInfo,
+ TransportProtos.GetAttributeRequestMsg.newBuilder().setOnlyShared(true).build(),
+ new CoapNoOpCallback(exchange));
}
break;
case UNSUBSCRIBE_ATTRIBUTES_REQUEST:
TransportProtos.SessionInfoProto attrSession = lookupAsyncSessionInfo(getTokenFromRequest(request));
if (attrSession != null) {
- UUID attrSessionId = new UUID(attrSession.getSessionIdMSB(), attrSession.getSessionIdLSB());
+ UUID attrSessionId = toSessionId(attrSession);
attributeSubscriptions.remove(attrSessionId);
+ sessionInfoToObserveRelationMap.remove(attrSession);
transportService.process(attrSession,
TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setUnsubscribe(true).build(),
new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
- closeAndDeregister(sessionInfo, sessionId);
+ closeAndDeregister(sessionInfo);
}
break;
case SUBSCRIBE_RPC_COMMANDS_REQUEST:
- TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionIdMap.get(getTokenFromRequest(request));
+ TransportProtos.SessionInfoProto currentRpcSession = tokenToSessionInfoMap.get(getTokenFromRequest(request));
if (currentRpcSession == null) {
rpcSubscriptions.add(sessionId);
registerAsyncCoapSession(exchange, sessionInfo, coapTransportAdaptor,
transportConfigurationContainer.getRpcRequestDynamicMessageBuilder(), getTokenFromRequest(request));
transportService.process(sessionInfo,
TransportProtos.SubscribeToRPCMsg.getDefaultInstance(),
- new CoapNoOpCallback(exchange));
- } else {
- UUID rpcSessionId = new UUID(currentRpcSession.getSessionIdMSB(), currentRpcSession.getSessionIdLSB());
- reportActivity(currentRpcSession, attributeSubscriptions.contains(rpcSessionId), rpcSubscriptions.contains(rpcSessionId));
+ new CoapOkCallback(exchange, CoAP.ResponseCode.VALID, CoAP.ResponseCode.INTERNAL_SERVER_ERROR)
+ );
}
break;
case UNSUBSCRIBE_RPC_COMMANDS_REQUEST:
TransportProtos.SessionInfoProto rpcSession = lookupAsyncSessionInfo(getTokenFromRequest(request));
if (rpcSession != null) {
- UUID rpcSessionId = new UUID(rpcSession.getSessionIdMSB(), rpcSession.getSessionIdLSB());
+ UUID rpcSessionId = toSessionId(rpcSession);
rpcSubscriptions.remove(rpcSessionId);
+ sessionInfoToObserveRelationMap.remove(rpcSession);
transportService.process(rpcSession,
TransportProtos.SubscribeToRPCMsg.newBuilder().setUnsubscribe(true).build(),
new CoapOkCallback(exchange, CoAP.ResponseCode.DELETED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
- closeAndDeregister(sessionInfo, sessionId);
+ closeAndDeregister(sessionInfo);
}
break;
case TO_DEVICE_RPC_RESPONSE:
@@ -329,10 +350,10 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
new CoapNoOpCallback(exchange));
break;
case GET_FIRMWARE_REQUEST:
- getFirmwareCallback(sessionInfo, exchange, FirmwareType.FIRMWARE);
+ getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.FIRMWARE);
break;
case GET_SOFTWARE_REQUEST:
- getFirmwareCallback(sessionInfo, exchange, FirmwareType.SOFTWARE);
+ getOtaPackageCallback(sessionInfo, exchange, OtaPackageType.SOFTWARE);
break;
}
} catch (AdaptorException e) {
@@ -341,29 +362,33 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
}
}
- private void getFirmwareCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, FirmwareType firmwareType) {
- TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder()
+ private UUID toSessionId(TransportProtos.SessionInfoProto sessionInfoProto) {
+ return new UUID(sessionInfoProto.getSessionIdMSB(), sessionInfoProto.getSessionIdLSB());
+ }
+
+ private void getOtaPackageCallback(TransportProtos.SessionInfoProto sessionInfo, CoapExchange exchange, OtaPackageType firmwareType) {
+ TransportProtos.GetOtaPackageRequestMsg requestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setType(firmwareType.name()).build();
- transportContext.getTransportService().process(sessionInfo, requestMsg, new FirmwareCallback(exchange));
+ transportContext.getTransportService().process(sessionInfo, requestMsg, new OtaPackageCallback(exchange));
}
private TransportProtos.SessionInfoProto lookupAsyncSessionInfo(String token) {
- tokenToNotificationCounterMap.remove(token);
- return tokenToSessionIdMap.remove(token);
+ tokenToObserveNotificationSeqMap.remove(token);
+ return tokenToSessionInfoMap.remove(token);
}
private void registerAsyncCoapSession(CoapExchange exchange, TransportProtos.SessionInfoProto sessionInfo, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder, String token) {
- tokenToSessionIdMap.putIfAbsent(token, sessionInfo);
+ tokenToSessionInfoMap.putIfAbsent(token, sessionInfo);
transportService.registerAsyncSession(sessionInfo, getCoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder));
transportService.process(sessionInfo, getSessionEventMsg(TransportProtos.SessionEvent.OPEN), null);
}
private CoapSessionListener getCoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) {
- return new CoapSessionListener(exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder);
+ return new CoapSessionListener(this, exchange, coapTransportAdaptor, rpcRequestDynamicMessageBuilder);
}
private String getTokenFromRequest(Request request) {
@@ -445,25 +470,25 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
}
}
- private class FirmwareCallback implements TransportServiceCallback {
+ private class OtaPackageCallback implements TransportServiceCallback {
private final CoapExchange exchange;
- FirmwareCallback(CoapExchange exchange) {
+ OtaPackageCallback(CoapExchange exchange) {
this.exchange = exchange;
}
@Override
- public void onSuccess(TransportProtos.GetFirmwareResponseMsg msg) {
+ public void onSuccess(TransportProtos.GetOtaPackageResponseMsg msg) {
String title = exchange.getQueryParameter("title");
String version = exchange.getQueryParameter("version");
if (msg.getResponseStatus().equals(TransportProtos.ResponseStatus.SUCCESS)) {
if (msg.getTitle().equals(title) && msg.getVersion().equals(version)) {
- String firmwareId = new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB()).toString();
+ String firmwareId = new UUID(msg.getOtaPackageIdMSB(), msg.getOtaPackageIdLSB()).toString();
String strChunkSize = exchange.getQueryParameter("size");
String strChunk = exchange.getQueryParameter("chunk");
int chunkSize = StringUtils.isEmpty(strChunkSize) ? 0 : Integer.parseInt(strChunkSize);
int chunk = StringUtils.isEmpty(strChunk) ? 0 : Integer.parseInt(strChunk);
- exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getFirmwareDataCache().get(firmwareId, chunkSize, chunk));
+ exchange.respond(CoAP.ResponseCode.CONTENT, transportContext.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk));
} else {
exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
}
@@ -481,11 +506,13 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
private static class CoapSessionListener implements SessionMsgListener {
+ private final CoapTransportResource coapTransportResource;
private final CoapExchange exchange;
private final CoapTransportAdaptor coapTransportAdaptor;
private final DynamicMessage.Builder rpcRequestDynamicMessageBuilder;
- CoapSessionListener(CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) {
+ CoapSessionListener(CoapTransportResource coapTransportResource, CoapExchange exchange, CoapTransportAdaptor coapTransportAdaptor, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) {
+ this.coapTransportResource = coapTransportResource;
this.exchange = exchange;
this.coapTransportAdaptor = coapTransportAdaptor;
this.rpcRequestDynamicMessageBuilder = rpcRequestDynamicMessageBuilder;
@@ -494,7 +521,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
@Override
public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg msg) {
try {
- exchange.respond(coapTransportAdaptor.convertToPublish(msg));
+ exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg));
} catch (AdaptorException e) {
log.trace("Failed to reply due to error", e);
exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
@@ -512,8 +539,21 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
}
@Override
- public void onRemoteSessionCloseCommand(TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
- exchange.respond(CoAP.ResponseCode.SERVICE_UNAVAILABLE);
+ public void onRemoteSessionCloseCommand(UUID sessionId, TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
+ log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
+ Map sessionToObserveRelationMap = coapTransportResource.getSessionInfoToObserveRelationMap();
+ if (coapTransportResource.getObserverCount() > 0 && !CollectionUtils.isEmpty(sessionToObserveRelationMap)) {
+ Set observeSessions = sessionToObserveRelationMap.keySet();
+ Optional observeSessionToClose = observeSessions.stream().filter(sessionInfoProto -> {
+ UUID observeSessionId = new UUID(sessionInfoProto.getSessionIdMSB(), sessionInfoProto.getSessionIdLSB());
+ return observeSessionId.equals(sessionId);
+ }).findFirst();
+ if (observeSessionToClose.isPresent()) {
+ TransportProtos.SessionInfoProto sessionInfoProto = observeSessionToClose.get();
+ ObserveRelation observeRelation = sessionToObserveRelationMap.get(sessionInfoProto);
+ coapTransportResource.clearAndNotifyObserveRelation(observeRelation, CoAP.ResponseCode.SERVICE_UNAVAILABLE);
+ }
+ }
}
@Override
@@ -529,7 +569,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
@Override
public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg msg) {
try {
- exchange.respond(coapTransportAdaptor.convertToPublish(msg));
+ exchange.respond(coapTransportAdaptor.convertToPublish(isConRequest(), msg));
} catch (AdaptorException e) {
log.trace("Failed to reply due to error", e);
exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
@@ -561,29 +601,29 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
@Override
public void addedObserveRelation(ObserveRelation relation) {
- if (log.isTraceEnabled()) {
- Request request = relation.getExchange().getRequest();
- log.trace("Added Observe relation for token: {}", getTokenFromRequest(request));
- }
+ Request request = relation.getExchange().getRequest();
+ String token = getTokenFromRequest(request);
+ sessionInfoToObserveRelationMap.putIfAbsent(tokenToSessionInfoMap.get(token), relation);
+ log.trace("Added Observe relation for token: {}", token);
}
@Override
public void removedObserveRelation(ObserveRelation relation) {
Request request = relation.getExchange().getRequest();
- String tokenFromRequest = getTokenFromRequest(request);
- log.trace("Relation removed for token: {}", tokenFromRequest);
- TransportProtos.SessionInfoProto sessionInfoToRemove = lookupAsyncSessionInfo(tokenFromRequest);
- if (sessionInfoToRemove != null) {
- closeAndDeregister(sessionInfoToRemove, new UUID(sessionInfoToRemove.getSessionIdMSB(), sessionInfoToRemove.getDeviceIdLSB()));
- }
+ String token = getTokenFromRequest(request);
+ TransportProtos.SessionInfoProto session = tokenToSessionInfoMap.get(token);
+ sessionInfoToObserveRelationMap.remove(session);
+ log.trace("Relation removed for token: {}", token);
}
}
- private void closeAndDeregister(TransportProtos.SessionInfoProto session, UUID sessionId) {
+ private void closeAndDeregister(TransportProtos.SessionInfoProto session) {
+ UUID sessionId = toSessionId(session);
transportService.process(session, getSessionEventMsg(TransportProtos.SessionEvent.CLOSED), null);
transportService.deregisterSession(session);
rpcSubscriptions.remove(sessionId);
attributeSubscriptions.remove(sessionId);
+ sessionInfoToObserveRelationMap.remove(session);
}
private TransportConfigurationContainer getTransportConfigurationContainer(DeviceProfile deviceProfile) throws AdaptorException {
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java
index a739563858..ce1618fe99 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java
@@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.CoapServer;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.TbTransportService;
import org.thingsboard.server.coapserver.CoapServerService;
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java
index f7572d0506..f94547b840 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java
@@ -40,6 +40,7 @@ public class CoapAdaptorUtils {
result.addAllSharedAttributeNames(sharedKeys);
}
}
+ result.setOnlyShared(false);
return result.build();
}
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java
index b30c86307b..00374f6916 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java
@@ -39,13 +39,13 @@ public interface CoapTransportAdaptor {
TransportProtos.ClaimDeviceMsg convertToClaimDevice(UUID sessionId, Request inbound, TransportProtos.SessionInfoProto sessionInfo) throws AdaptorException;
- Response convertToPublish(TransportProtos.GetAttributeResponseMsg responseMsg) throws AdaptorException;
+ Response convertToPublish(boolean isConfirmable, TransportProtos.GetAttributeResponseMsg responseMsg) throws AdaptorException;
Response convertToPublish(boolean isConfirmable, TransportProtos.AttributeUpdateNotificationMsg notificationMsg) throws AdaptorException;
Response convertToPublish(boolean isConfirmable, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, DynamicMessage.Builder rpcRequestDynamicMessageBuilder) throws AdaptorException;
- Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException;
+ Response convertToPublish(boolean isConfirmable, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException;
ProvisionDeviceRequestMsg convertToProvisionRequestMsg(UUID sessionId, Request inbound) throws AdaptorException;
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
index 85d35301c3..4b4369f222 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
@@ -26,12 +26,14 @@ import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.coap.Response;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.coap.CoapTransportResource;
+import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -101,10 +103,11 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
}
@Override
- public Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException {
+ public Response convertToPublish(boolean isConfirmable, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException {
Response response = new Response(CoAP.ResponseCode.CONTENT);
JsonElement result = JsonConverter.toJson(msg);
response.setPayload(result.toString());
+ response.setAcknowledged(isConfirmable);
return response;
}
@@ -119,21 +122,35 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
}
@Override
- public Response convertToPublish(TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
- if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
- return new Response(CoAP.ResponseCode.NOT_FOUND);
+ public Response convertToPublish(boolean isConfirmable, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
+ if (msg.getSharedStateMsg()) {
+ if (StringUtils.isEmpty(msg.getError())) {
+ Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ response.setAcknowledged(isConfirmable);
+ TransportProtos.AttributeUpdateNotificationMsg notificationMsg = TransportProtos.AttributeUpdateNotificationMsg.newBuilder().addAllSharedUpdated(msg.getSharedAttributeListList()).build();
+ JsonObject result = JsonConverter.toJson(notificationMsg);
+ response.setPayload(result.toString());
+ return response;
+ } else {
+ return new Response(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
+ }
} else {
- Response response = new Response(CoAP.ResponseCode.CONTENT);
- JsonObject result = JsonConverter.toJson(msg);
- response.setPayload(result.toString());
- return response;
+ if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
+ return new Response(CoAP.ResponseCode.NOT_FOUND);
+ } else {
+ Response response = new Response(CoAP.ResponseCode.CONTENT);
+ response.setAcknowledged(isConfirmable);
+ JsonObject result = JsonConverter.toJson(msg);
+ response.setPayload(result.toString());
+ return response;
+ }
}
}
private Response getObserveNotification(boolean confirmable, JsonElement json) {
- Response response = new Response(CoAP.ResponseCode.CONTENT);
+ Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
response.setPayload(json.toString());
- response.setConfirmable(confirmable);
+ response.setAcknowledged(confirmable);
return response;
}
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java
index 120e49f697..2ab377611c 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.transport.coap.adaptors;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.protobuf.Descriptors;
import com.google.protobuf.DynamicMessage;
@@ -26,6 +27,7 @@ import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.coap.Response;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@@ -118,27 +120,41 @@ public class ProtoCoapAdaptor implements CoapTransportAdaptor {
}
@Override
- public Response convertToPublish(TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException {
+ public Response convertToPublish(boolean isConfirmable, TransportProtos.ToServerRpcResponseMsg msg) throws AdaptorException {
Response response = new Response(CoAP.ResponseCode.CONTENT);
+ response.setAcknowledged(isConfirmable);
response.setPayload(msg.toByteArray());
return response;
}
@Override
- public Response convertToPublish(TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
- if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
- return new Response(CoAP.ResponseCode.NOT_FOUND);
+ public Response convertToPublish(boolean isConfirmable, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
+ if (msg.getSharedStateMsg()) {
+ if (StringUtils.isEmpty(msg.getError())) {
+ Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
+ response.setAcknowledged(isConfirmable);
+ TransportProtos.AttributeUpdateNotificationMsg notificationMsg = TransportProtos.AttributeUpdateNotificationMsg.newBuilder().addAllSharedUpdated(msg.getSharedAttributeListList()).build();
+ response.setPayload(notificationMsg.toByteArray());
+ return response;
+ } else {
+ return new Response(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
+ }
} else {
- Response response = new Response(CoAP.ResponseCode.CONTENT);
- response.setPayload(msg.toByteArray());
- return response;
+ if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
+ return new Response(CoAP.ResponseCode.NOT_FOUND);
+ } else {
+ Response response = new Response(CoAP.ResponseCode.CONTENT);
+ response.setAcknowledged(isConfirmable);
+ response.setPayload(msg.toByteArray());
+ return response;
+ }
}
}
private Response getObserveNotification(boolean confirmable, byte[] notification) {
- Response response = new Response(CoAP.ResponseCode.CONTENT);
+ Response response = new Response(CoAP.ResponseCode._UNKNOWN_SUCCESS_CODE);
response.setPayload(notification);
- response.setConfirmable(confirmable);
+ response.setAcknowledged(confirmable);
return response;
}
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/NoSecObserveClient.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/NoSecObserveClient.java
new file mode 100644
index 0000000000..3340fdd61b
--- /dev/null
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/NoSecObserveClient.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.transport.coap.client;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.californium.core.CoapClient;
+import org.eclipse.californium.core.CoapHandler;
+import org.eclipse.californium.core.CoapObserveRelation;
+import org.eclipse.californium.core.CoapResponse;
+import org.eclipse.californium.core.coap.CoAP;
+import org.eclipse.californium.core.coap.Request;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+public class NoSecObserveClient {
+
+ private static final long INFINIT_EXCHANGE_LIFETIME = 0L;
+
+ private CoapClient coapClient;
+ private CoapObserveRelation observeRelation;
+ private ExecutorService executor = Executors.newFixedThreadPool(1);
+ private CountDownLatch latch;
+
+ public NoSecObserveClient(String host, int port, String accessToken) throws URISyntaxException {
+ URI uri = new URI(getFutureUrl(host, port, accessToken));
+ this.coapClient = new CoapClient(uri);
+ coapClient.setTimeout(INFINIT_EXCHANGE_LIFETIME);
+ this.latch = new CountDownLatch(5);
+ }
+
+ public void start() {
+ executor.submit(() -> {
+ try {
+ Request request = Request.newGet();
+ request.setObserve();
+ observeRelation = coapClient.observe(request, new CoapHandler() {
+ @Override
+ public void onLoad(CoapResponse response) {
+ String responseText = response.getResponseText();
+ CoAP.ResponseCode code = response.getCode();
+ Integer observe = response.getOptions().getObserve();
+ log.info("CoAP Response received! " +
+ "responseText: {}, " +
+ "code: {}, " +
+ "observe seq number: {}",
+ responseText,
+ code,
+ observe);
+ latch.countDown();
+ }
+
+ @Override
+ public void onError() {
+ log.error("Ack error!");
+ latch.countDown();
+ }
+ });
+ } catch (Exception e) {
+ log.error("Error occurred while sending COAP requests: ");
+ }
+ });
+ try {
+ latch.await();
+ observeRelation.proactiveCancel();
+ } catch (InterruptedException e) {
+ log.error("Error occurred: ", e);
+ }
+ }
+
+ private String getFutureUrl(String host, Integer port, String accessToken) {
+ return "coap://" + host + ":" + port + "/api/v1/" + accessToken + "/attributes";
+ }
+
+ public static void main(String[] args) throws URISyntaxException {
+ log.info("Usage: java -cp ... org.thingsboard.server.transport.coap.client.NoSecObserveClient " +
+ "host port accessToken");
+
+ String host = args[0];
+ int port = Integer.parseInt(args[1]);
+ String accessToken = args[2];
+
+ final NoSecObserveClient client = new NoSecObserveClient(host, port, accessToken);
+ client.start();
+ }
+}
diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java
index 03ed92da58..d53cd7e49e 100644
--- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java
+++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java
@@ -87,7 +87,7 @@ public class CoapEfentoTransportResource extends AbstractCoapTransportResource {
transportService.process(sessionInfo,
transportContext.getEfentoCoapAdaptor().convertToPostTelemetry(sessionId, efentoMeasurements),
new CoapOkCallback(exchange, CoAP.ResponseCode.CREATED, CoAP.ResponseCode.INTERNAL_SERVER_ERROR));
- reportActivity(sessionInfo, false, false);
+ reportSubscriptionInfo(sessionInfo, false, false);
} catch (AdaptorException e) {
log.error("[{}] Failed to decode Efento ProtoMeasurements: ", sessionId, e);
exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
index bb9499ae29..f4a3f705af 100644
--- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
+++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
@@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.server.common.data.DeviceTransportType;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.TbTransportService;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.transport.SessionMsgListener;
@@ -213,7 +213,7 @@ public class DeviceApiController implements TbTransportService {
@RequestParam(value = "version") String version,
@RequestParam(value = "size", required = false, defaultValue = "0") int size,
@RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
- return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.FIRMWARE);
+ return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE);
}
@RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET)
@@ -222,7 +222,7 @@ public class DeviceApiController implements TbTransportService {
@RequestParam(value = "version") String version,
@RequestParam(value = "size", required = false, defaultValue = "0") int size,
@RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) {
- return getFirmwareCallback(deviceToken, title, version, size, chunk, FirmwareType.SOFTWARE);
+ return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE);
}
@RequestMapping(value = "/provision", method = RequestMethod.POST)
@@ -233,17 +233,17 @@ public class DeviceApiController implements TbTransportService {
return responseWriter;
}
- private DeferredResult getFirmwareCallback(String deviceToken, String title, String version, int size, int chunk, FirmwareType firmwareType) {
+ private DeferredResult getOtaPackageCallback(String deviceToken, String title, String version, int size, int chunk, OtaPackageType firmwareType) {
DeferredResult responseWriter = new DeferredResult<>();
transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(),
new DeviceAuthCallback(transportContext, responseWriter, sessionInfo -> {
- TransportProtos.GetFirmwareRequestMsg requestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder()
+ TransportProtos.GetOtaPackageRequestMsg requestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setType(firmwareType.name()).build();
- transportContext.getTransportService().process(sessionInfo, requestMsg, new GetFirmwareCallback(responseWriter, title, version, size, chunk));
+ transportContext.getTransportService().process(sessionInfo, requestMsg, new GetOtaPackageCallback(responseWriter, title, version, size, chunk));
}));
return responseWriter;
}
@@ -294,14 +294,14 @@ public class DeviceApiController implements TbTransportService {
}
}
- private class GetFirmwareCallback implements TransportServiceCallback {
+ private class GetOtaPackageCallback implements TransportServiceCallback {
private final DeferredResult responseWriter;
private final String title;
private final String version;
private final int chuckSize;
private final int chuck;
- GetFirmwareCallback(DeferredResult responseWriter, String title, String version, int chuckSize, int chuck) {
+ GetOtaPackageCallback(DeferredResult responseWriter, String title, String version, int chuckSize, int chuck) {
this.responseWriter = responseWriter;
this.title = title;
this.version = version;
@@ -310,17 +310,17 @@ public class DeviceApiController implements TbTransportService {
}
@Override
- public void onSuccess(TransportProtos.GetFirmwareResponseMsg firmwareResponseMsg) {
- if (!TransportProtos.ResponseStatus.SUCCESS.equals(firmwareResponseMsg.getResponseStatus())) {
+ public void onSuccess(TransportProtos.GetOtaPackageResponseMsg otaPackageResponseMsg) {
+ if (!TransportProtos.ResponseStatus.SUCCESS.equals(otaPackageResponseMsg.getResponseStatus())) {
responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_FOUND));
- } else if (title.equals(firmwareResponseMsg.getTitle()) && version.equals(firmwareResponseMsg.getVersion())) {
- String firmwareId = new UUID(firmwareResponseMsg.getFirmwareIdMSB(), firmwareResponseMsg.getFirmwareIdLSB()).toString();
- ByteArrayResource resource = new ByteArrayResource(transportContext.getFirmwareDataCache().get(firmwareId, chuckSize, chuck));
+ } else if (title.equals(otaPackageResponseMsg.getTitle()) && version.equals(otaPackageResponseMsg.getVersion())) {
+ String otaPackageId = new UUID(otaPackageResponseMsg.getOtaPackageIdMSB(), otaPackageResponseMsg.getOtaPackageIdLSB()).toString();
+ ByteArrayResource resource = new ByteArrayResource(transportContext.getOtaPackageDataCache().get(otaPackageId, chuckSize, chuck));
ResponseEntity response = ResponseEntity.ok()
- .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + firmwareResponseMsg.getFileName())
- .header("x-filename", firmwareResponseMsg.getFileName())
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackageResponseMsg.getFileName())
+ .header("x-filename", otaPackageResponseMsg.getFileName())
.contentLength(resource.contentLength())
- .contentType(parseMediaType(firmwareResponseMsg.getContentType()))
+ .contentType(parseMediaType(otaPackageResponseMsg.getContentType()))
.body(resource);
responseWriter.setResult(response);
} else {
@@ -391,7 +391,8 @@ public class DeviceApiController implements TbTransportService {
}
@Override
- public void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification) {
+ public void onRemoteSessionCloseCommand(UUID sessionId, SessionCloseNotificationProto sessionCloseNotification) {
+ log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT));
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java
index 986085a7c9..e0a85bc77d 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java
@@ -23,6 +23,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.LwM2mObject;
@@ -38,13 +39,13 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardExecutors;
-import org.thingsboard.server.cache.firmware.FirmwareDataCache;
+import org.thingsboard.server.cache.ota.OtaPackageDataCache;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
-import org.thingsboard.server.common.data.firmware.FirmwareKey;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.firmware.FirmwareUtil;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.ota.OtaPackageKey;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.ota.OtaPackageUtil;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
@@ -61,6 +62,7 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;
+import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue;
import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto;
import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters;
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
@@ -85,8 +87,8 @@ import java.util.stream.Collectors;
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST;
import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED;
@@ -99,21 +101,21 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER;
-import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_All;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
-import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
-import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_RESULT_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getAckCallback;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.isFwSwWords;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.setValidTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validateObjectVerFromKey;
@@ -125,32 +127,33 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
private ExecutorService registrationExecutor;
private ExecutorService updateRegistrationExecutor;
private ExecutorService unRegistrationExecutor;
- private LwM2mValueConverterImpl converter;
+ public LwM2mValueConverterImpl converter;
private final TransportService transportService;
private final LwM2mTransportContext context;
public final LwM2MTransportServerConfig config;
- public final FirmwareDataCache firmwareDataCache;
+ public final OtaPackageDataCache otaPackageDataCache;
public final LwM2mTransportServerHelper helper;
private final LwM2MJsonAdaptor adaptor;
- private final LwM2mClientContext clientContext;
- private final LwM2mTransportRequest lwM2mTransportRequest;
private final TbLwM2MDtlsSessionStore sessionStore;
-
+ public final LwM2mClientContext clientContext;
+ public final LwM2mTransportRequest lwM2mTransportRequest;
+ private final Map rpcSubscriptions;
public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper,
LwM2mClientContext clientContext,
@Lazy LwM2mTransportRequest lwM2mTransportRequest,
- FirmwareDataCache firmwareDataCache,
+ OtaPackageDataCache otaPackageDataCache,
LwM2mTransportContext context, LwM2MJsonAdaptor adaptor, TbLwM2MDtlsSessionStore sessionStore) {
this.transportService = transportService;
this.config = config;
this.helper = helper;
this.clientContext = clientContext;
this.lwM2mTransportRequest = lwM2mTransportRequest;
- this.firmwareDataCache = firmwareDataCache;
+ this.otaPackageDataCache = otaPackageDataCache;
this.context = context;
this.adaptor = adaptor;
+ this.rpcSubscriptions = new ConcurrentHashMap<>();
this.sessionStore = sessionStore;
}
@@ -193,8 +196,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
.setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build())
.build();
transportService.process(msg, null);
- this.getInfoFirmwareUpdate(lwM2MClient);
- this.getInfoSoftwareUpdate(lwM2MClient);
+ this.getInfoFirmwareUpdate(lwM2MClient, null);
+ this.getInfoSoftwareUpdate(lwM2MClient, null);
this.initLwM2mFromClientValue(registration, lwM2MClient);
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId());
} else {
@@ -241,16 +244,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
/**
* @param registration - Registration LwM2M Client
- * @param observations - All paths observations before unReg
- * !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect
+ * @param observations - !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect
*/
public void unReg(Registration registration, Collection observations) {
unRegistrationExecutor.submit(() -> {
try {
- this.setCancelObservationsAll(registration);
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId());
this.closeClientSession(registration);
- ;
} catch (Throwable t) {
log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t);
this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId());
@@ -285,12 +285,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
@Override
public void setCancelObservationsAll(Registration registration) {
if (registration != null) {
- lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL,
+ this.lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL_ALL,
null, null, this.config.getTimeout(), null);
-// Set observations = context.getServer().getObservationService().getObservations(registration);
-// observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration,
-// convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL,
-// null, null, this.config.getTimeout(), null));
}
}
@@ -338,7 +334,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
READ, pathIdVer, value);
this.sendLogsToThingsboard(msg, registration.getId());
rpcRequest.setValueMsg(String.format("%s", value));
- this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
+ this.sentRpcResponse(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
}
/**
@@ -354,22 +350,23 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
*/
@Override
public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) {
- LwM2mClient lwM2MClient = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
- if (msg.getSharedUpdatedCount() > 0) {
+ LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo);
+ if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) {
+ log.warn ("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList());
msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey();
String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName);
Object valueNew = getValueFromKvProto(tsKvProto.getKv());
- if ((FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName)
+ if ((OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())))
- || (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.TITLE).equals(pathName)
+ || (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentTitle())))) {
- this.getInfoFirmwareUpdate(lwM2MClient);
- } else if ((FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.VERSION).equals(pathName)
+ this.getInfoFirmwareUpdate(lwM2MClient, null);
+ } else if ((OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentVersion())))
- || (FirmwareUtil.getAttributeKey(FirmwareType.SOFTWARE, FirmwareKey.TITLE).equals(pathName)
+ || (OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentTitle())))) {
- this.getInfoSoftwareUpdate(lwM2MClient);
+ this.getInfoSoftwareUpdate(lwM2MClient, null);
}
if (pathIdVer != null) {
ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.config
@@ -382,7 +379,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
LOG_LW2M_ERROR, pathIdVer, valueNew);
this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId());
}
- } else {
+ } else if (!isFwSwWords(pathName)) {
log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew);
String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated",
LOG_LW2M_ERROR, pathName, valueNew);
@@ -390,16 +387,19 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
}
});
- } else if (msg.getSharedDeletedCount() > 0) {
+ } else if (msg.getSharedDeletedCount() > 0 && lwM2MClient != null) {
msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey();
Object valueNew = getValueFromKvProto(tsKvProto.getKv());
- if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())) {
+ if (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())) {
lwM2MClient.getFwUpdate().setCurrentVersion((String) valueNew);
}
});
log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo);
}
+ else if (lwM2MClient == null) {
+ log.error ("OnAttributeUpdate, lwM2MClient is null");
+ }
}
/**
@@ -438,124 +438,52 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider()));
}
+ /**
+ * #1 del from rpcSubscriptions by timeout
+ * #2 if not present in rpcSubscriptions by requestId: create new Lwm2mClientRpcRequest, after success - add requestId, timeout
+ */
@Override
public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) {
- log.warn("4) RPC-OK finish to [{}]", toDeviceRpcRequestMsg);
- Lwm2mClientRpcRequest lwm2mClientRpcRequest = null;
- try {
- Registration registration = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration();
- lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRpcRequestMsg, sessionInfo, registration);
- if (lwm2mClientRpcRequest.getErrorMsg() != null) {
- lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
- this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
- } else {
- lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), lwm2mClientRpcRequest.getContentFormatName(),
- lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(),
- this.config.getTimeout(), lwm2mClientRpcRequest);
- }
- } catch (Exception e) {
- if (lwm2mClientRpcRequest == null) {
- lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
- }
- lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
- if (lwm2mClientRpcRequest.getErrorMsg() == null) {
- lwm2mClientRpcRequest.setErrorMsg(e.getMessage());
- }
- this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
- }
- }
-
- private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest,
- SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException {
- Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
- try {
- lwm2mClientRpcRequest.setRequestId(toDeviceRequest.getRequestId());
- lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
- lwm2mClientRpcRequest.setValidTypeOper(toDeviceRequest.getMethodName());
- JsonObject rpcRequest = LwM2mTransportUtil.validateJson(toDeviceRequest.getParams());
- if (rpcRequest != null) {
- if (rpcRequest.has(lwm2mClientRpcRequest.keyNameKey)) {
- String targetIdVer = this.getPresentPathIntoProfile(sessionInfo,
- rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString());
- if (targetIdVer != null) {
- lwm2mClientRpcRequest.setTargetIdVer(targetIdVer);
- lwm2mClientRpcRequest.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s",
- rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString(), targetIdVer));
- }
- }
- if (lwm2mClientRpcRequest.getTargetIdVer() == null) {
- lwm2mClientRpcRequest.setValidTargetIdVerKey(rpcRequest, registration);
- }
- if (rpcRequest.has(lwm2mClientRpcRequest.contentFormatNameKey)) {
- lwm2mClientRpcRequest.setValidContentFormatName(rpcRequest);
- }
- if (rpcRequest.has(lwm2mClientRpcRequest.timeoutInMsKey) && rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong() > 0) {
- lwm2mClientRpcRequest.setTimeoutInMs(rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong());
- }
- if (rpcRequest.has(lwm2mClientRpcRequest.valueKey)) {
- lwm2mClientRpcRequest.setValue(rpcRequest.get(lwm2mClientRpcRequest.valueKey).getAsString());
- }
- if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) {
- ConcurrentHashMap params = new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey)
- .getAsJsonObject().toString(), new TypeToken>() {
- }.getType());
- if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()) {
- ConcurrentHashMap paramsResourceId = convertParamsToResourceId(params, sessionInfo);
- if (paramsResourceId.size() > 0) {
- lwm2mClientRpcRequest.setParams(paramsResourceId);
- }
- } else {
- lwm2mClientRpcRequest.setParams(params);
- }
- } else if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonArray()) {
- new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey)
- .getAsJsonObject().toString(), new TypeToken>() {
- }.getType());
+ // #1
+ this.checkRpcRequestTimeout();
+ log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
+ String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null";
+ LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName());
+ UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB());
+ if (!this.rpcSubscriptions.containsKey(requestUUID)) {
+ this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime());
+ Lwm2mClientRpcRequest lwm2mClientRpcRequest = null;
+ try {
+ Registration registration = clientContext.getClient(sessionInfo).getRegistration();
+ lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this);
+ if (lwm2mClientRpcRequest.getErrorMsg() != null) {
+ lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
+ this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
+ } else {
+ lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(),
+ null,
+ lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(),
+ this.config.getTimeout(), lwm2mClientRpcRequest);
}
- lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
- if (!(OBSERVE_READ_ALL == lwm2mClientRpcRequest.getTypeOper()
- || DISCOVER_All == lwm2mClientRpcRequest.getTypeOper()
- || OBSERVE_CANCEL == lwm2mClientRpcRequest.getTypeOper())
- && lwm2mClientRpcRequest.getTargetIdVer() == null) {
- lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " +
- lwm2mClientRpcRequest.keyNameKey + " is null or bad format");
+ } catch (Exception e) {
+ if (lwm2mClientRpcRequest == null) {
+ lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
}
- /**
- * EXECUTE && WRITE_REPLACE - only for Resource or ResourceInstance
- */
- else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper()
- || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper())
- && lwm2mClientRpcRequest.getTargetIdVer() != null
- && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource()
- || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) {
- lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey
- + ". Only Resource or ResourceInstance can be this operation");
+ lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
+ if (lwm2mClientRpcRequest.getErrorMsg() == null) {
+ lwm2mClientRpcRequest.setErrorMsg(e.getMessage());
}
- } else {
- lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format.");
+ this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
}
- } catch (Exception e) {
- throw new IllegalArgumentException(lwm2mClientRpcRequest.getErrorMsg());
}
- return lwm2mClientRpcRequest;
}
- private ConcurrentHashMap convertParamsToResourceId(ConcurrentHashMap params,
- SessionInfoProto sessionInfo) {
- ConcurrentHashMap paramsIdVer = new ConcurrentHashMap<>();
- params.forEach((k, v) -> {
- String targetIdVer = this.getPresentPathIntoProfile(sessionInfo, k);
- if (targetIdVer != null) {
- LwM2mPath targetId = new LwM2mPath(convertPathFromIdVerToObjectId(targetIdVer));
- if (targetId.isResource()) {
- paramsIdVer.put(String.valueOf(targetId.getResourceId()), v);
- }
- }
- });
- return paramsIdVer;
+ private void checkRpcRequestTimeout() {
+ Set rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> System.currentTimeMillis() > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet());
+ rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove);
}
- public void sentRpcRequest(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) {
+ public void sentRpcResponse(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) {
rpcRequest.setResponseCode(requestCode);
if (LOG_LW2M_ERROR.equals(typeMsg)) {
rpcRequest.setInfoMsg(null);
@@ -578,6 +506,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
@Override
public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) {
+ log.warn ("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
transportService.process(sessionInfo, toDeviceResponse, null);
}
@@ -722,10 +651,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
* set setClient_fw_info... = value
**/
if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) {
- lwM2MClient.getFwUpdate().initReadValue(this, lwM2mTransportRequest, path);
+ lwM2MClient.getFwUpdate().initReadValue(this, this.lwM2mTransportRequest, path);
}
if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) {
- lwM2MClient.getSwUpdate().initReadValue(this, lwM2mTransportRequest, path);
+ lwM2MClient.getSwUpdate().initReadValue(this, this.lwM2mTransportRequest, path);
}
/**
@@ -742,7 +671,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
&& (convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) {
if (DOWNLOADED.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
&& lwM2MClient.getFwUpdate().conditionalFwExecuteStart()) {
- lwM2MClient.getFwUpdate().executeFwSwWare(this, lwM2mTransportRequest);
+ lwM2MClient.getFwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest);
} else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
&& lwM2MClient.getFwUpdate().conditionalFwExecuteAfterSuccess()) {
lwM2MClient.getFwUpdate().finishFwSwUpdate(this, true);
@@ -767,7 +696,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
&& (convertPathFromObjectIdToIdVer(SW_RESULT_ID, registration).equals(path))) {
if (DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())
&& lwM2MClient.getSwUpdate().conditionalSwUpdateExecute()) {
- lwM2MClient.getSwUpdate().executeFwSwWare(this, lwM2mTransportRequest);
+ lwM2MClient.getSwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest);
} else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())
&& lwM2MClient.getSwUpdate().conditionalSwExecuteAfterSuccess()) {
lwM2MClient.getSwUpdate().finishFwSwUpdate(this, true);
@@ -958,10 +887,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
*/
private Object getResourceValueFormatKv(LwM2mClient lwM2MClient, String pathIdVer) {
LwM2mResource resourceValue = this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer);
- ResourceModel.Type currentType = resourceValue.getType();
- ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer);
- return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType,
- new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)));
+ if (resourceValue != null) {
+ ResourceModel.Type currentType = resourceValue.getType();
+ ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer);
+ return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType,
+ new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)));
+ }
+
+ else {
+ return null;
+ }
}
/**
@@ -970,11 +905,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
* @return - return value of Resource by idPath
*/
private LwM2mResource getResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) {
- LwM2mResource resourceValue = null;
- if (new LwM2mPath(convertPathFromIdVerToObjectId(path)).isResource()) {
- resourceValue = lwM2MClient.getResources().get(path).getLwM2mResource();
+ LwM2mResource lwm2mResourceValue = null;
+ ResourceValue resourceValue = lwM2MClient.getResources().get(path);
+ if (resourceValue != null) {
+ if (new LwM2mPath(convertPathFromIdVerToObjectId(path)).isResource()) {
+ lwm2mResourceValue = lwM2MClient.getResources().get(path).getLwM2mResource();
+ }
}
- return resourceValue;
+ return lwm2mResourceValue;
}
/**
@@ -1281,7 +1219,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
* @param name -
* @return -
*/
- private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
+ public String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {
LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo);
return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
@@ -1301,10 +1239,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) {
try {
List tsKvProtos = attributesResponse.getSharedAttributeListList();
-
this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo);
} catch (Exception e) {
- log.error(String.valueOf(e));
+ log.error("", e);
}
}
@@ -1320,22 +1257,28 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
*/
public void updateAttributeFromThingsboard(List tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) {
LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo);
- tsKvProtos.forEach(tsKvProto -> {
- String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey());
- if (pathIdVer != null) {
- // #1.1
- if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) {
- lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
- } else if (!lwM2MClient.getDelayedRequests().containsKey(pathIdVer)) {
- lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
+ if (lwM2MClient != null) {
+ log.warn("1) UpdateAttributeFromThingsboard, tsKvProtos [{}]", tsKvProtos);
+ tsKvProtos.forEach(tsKvProto -> {
+ String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey());
+ if (pathIdVer != null) {
+ // #1.1
+ if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) {
+ lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
+ } else if (!lwM2MClient.getDelayedRequests().containsKey(pathIdVer)) {
+ lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
+ }
}
- }
- });
- // #2.1
- lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> {
- this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer),
- getValueFromKvProto(tsKvProto.getKv()), pathIdVer);
- });
+ });
+ // #2.1
+ lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> {
+ this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer),
+ getValueFromKvProto(tsKvProto.getKv()), pathIdVer);
+ });
+ }
+ else {
+ log.error("UpdateAttributeFromThingsboard, lwM2MClient is null");
+ }
}
/**
@@ -1378,6 +1321,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
private void reportActivityAndRegister(SessionInfoProto sessionInfo) {
if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) {
transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo));
+ this.reportActivitySubscription(sessionInfo);
}
}
@@ -1413,23 +1357,30 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
}
}
- public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) {
+ public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) {
if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) {
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
if (sessionInfo != null) {
- DefaultLwM2MTransportMsgHandler serviceImpl = this;
- transportService.process(sessionInfo, createFirmwareRequestMsg(sessionInfo, FirmwareType.FIRMWARE.name()),
+ DefaultLwM2MTransportMsgHandler handler = this;
+ this.transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()),
new TransportServiceCallback<>() {
@Override
- public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) {
+ public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) {
if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())
- && response.getType().equals(FirmwareType.FIRMWARE.name())) {
+ && response.getType().equals(OtaPackageType.FIRMWARE.name())) {
+ log.warn ("7) firmware start with ver: [{}]", response.getVersion());
+ lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest);
lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion());
lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle());
- lwM2MClient.getFwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId());
- lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
+ lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId());
+ if (rpcRequest == null) {
+ lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
+ }
+ else {
+ lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest);
+ }
} else {
- log.trace("Firmware [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
+ log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
}
}
@@ -1442,21 +1393,28 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
}
}
- public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient) {
+ public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) {
if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) {
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
if (sessionInfo != null) {
- DefaultLwM2MTransportMsgHandler serviceImpl = this;
- transportService.process(sessionInfo, createFirmwareRequestMsg(sessionInfo, FirmwareType.SOFTWARE.name()),
+ DefaultLwM2MTransportMsgHandler handler = this;
+ transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()),
new TransportServiceCallback<>() {
@Override
- public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) {
+ public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) {
if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())
- && response.getType().equals(FirmwareType.SOFTWARE.name())) {
+ && response.getType().equals(OtaPackageType.SOFTWARE.name())) {
+ lwM2MClient.getSwUpdate().setRpcRequest(rpcRequest);
lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion());
lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle());
- lwM2MClient.getSwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId());
+ lwM2MClient.getSwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId());
lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
+ if (rpcRequest == null) {
+ lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
+ }
+ else {
+ lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest);
+ }
} else {
log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
}
@@ -1471,8 +1429,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
}
}
- private TransportProtos.GetFirmwareRequestMsg createFirmwareRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) {
- return TransportProtos.GetFirmwareRequestMsg.newBuilder()
+ private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) {
+ return TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
@@ -1510,4 +1468,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
return this.config;
}
+ private void reportActivitySubscription(TransportProtos.SessionInfoProto sessionInfo) {
+ transportService.process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder()
+ .setAttributeSubscription(true)
+ .setRpcSubscription(true)
+ .setLastActivityTime(System.currentTimeMillis())
+ .build(), TransportServiceCallback.EMPTY);
+ }
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java
index 3de5846ca0..280cb7dde4 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mNetworkConfig.java
@@ -23,26 +23,26 @@ public class LwM2mNetworkConfig {
NetworkConfig coapConfig = new NetworkConfig();
coapConfig.setInt(NetworkConfig.Keys.COAP_PORT,serverPortNoSec);
coapConfig.setInt(NetworkConfig.Keys.COAP_SECURE_PORT,serverSecurePort);
- /*
- Example:Property for large packet:
- #NetworkConfig config = new NetworkConfig();
- #config.setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE,32);
- #config.setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE,32);
- #config.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE,2048);
- #config.setInt(NetworkConfig.Keys.MAX_RETRANSMIT,3);
- #config.setInt(NetworkConfig.Keys.MAX_TRANSMIT_WAIT,120000);
+ /**
+ Example:Property for large packet:
+ #NetworkConfig config = new NetworkConfig();
+ #config.setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE,32);
+ #config.setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE,32);
+ #config.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE,2048);
+ #config.setInt(NetworkConfig.Keys.MAX_RETRANSMIT,3);
+ #config.setInt(NetworkConfig.Keys.MAX_TRANSMIT_WAIT,120000);
*/
- /*
- Property to indicate if the response should always include the Block2 option \
- when client request early blockwise negociation but the response can be sent on one packet.
- - value of false indicate that the server will respond without block2 option if no further blocks are required.
- - value of true indicate that the server will response with block2 option event if no further blocks are required.
- CoAP client will try to use block mode
- or adapt the block size when receiving a 4.13 Entity too large response code
+ /**
+ Property to indicate if the response should always include the Block2 option \
+ when client request early blockwise negociation but the response can be sent on one packet.
+ - value of false indicate that the server will respond without block2 option if no further blocks are required.
+ - value of true indicate that the server will response with block2 option event if no further blocks are required.
+ CoAP client will try to use block mode
+ or adapt the block size when receiving a 4.13 Entity too large response code
*/
coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, true);
- /*
+ /**
Property to indicate if the response should always include the Block2 option \
when client request early blockwise negociation but the response can be sent on one packet.
- value of false indicate that the server will respond without block2 option if no further blocks are required.
@@ -51,44 +51,44 @@ public class LwM2mNetworkConfig {
coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_ENTITY_TOO_LARGE_AUTO_FAILOVER, true);
coapConfig.setInt(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, 300000);
- /*
- !!! REQUEST_ENTITY_TOO_LARGE CODE=4.13
- The maximum size of a resource body (in bytes) that will be accepted
- as the payload of a POST/PUT or the response to a GET request in a
- transparent> blockwise transfer.
- This option serves as a safeguard against excessive memory
- consumption when many resources contain large bodies that cannot be
- transferred in a single CoAP message. This option has no impact on
- *manually* managed blockwise transfers in which the blocks are handled individually.
- Note that this option does not prevent local clients or resource
- implementations from sending large bodies as part of a request or response to a peer.
- The default value of this property is DEFAULT_MAX_RESOURCE_BODY_SIZE = 8192
- A value of {@code 0} turns off transparent handling of blockwise transfers altogether.
+ /**
+ !!! REQUEST_ENTITY_TOO_LARGE CODE=4.13
+ The maximum size of a resource body (in bytes) that will be accepted
+ as the payload of a POST/PUT or the response to a GET request in a
+ transparent> blockwise transfer.
+ This option serves as a safeguard against excessive memory
+ consumption when many resources contain large bodies that cannot be
+ transferred in a single CoAP message. This option has no impact on
+ *manually* managed blockwise transfers in which the blocks are handled individually.
+ Note that this option does not prevent local clients or resource
+ implementations from sending large bodies as part of a request or response to a peer.
+ The default value of this property is DEFAULT_MAX_RESOURCE_BODY_SIZE = 8192
+ A value of {@code 0} turns off transparent handling of blockwise transfers altogether.
*/
coapConfig.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE, 256 * 1024 * 1024);
- /*
- The default DTLS response matcher.
- Supported values are STRICT, RELAXED, or PRINCIPAL.
- The default value is STRICT.
- Create new instance of udp endpoint context matcher.
- Params:
- checkAddress
- – true with address check, (STRICT, UDP)
- - false, without
+ /**
+ The default DTLS response matcher.
+ Supported values are STRICT, RELAXED, or PRINCIPAL.
+ The default value is STRICT.
+ Create new instance of udp endpoint context matcher.
+ Params:
+ checkAddress
+ – true with address check, (STRICT, UDP)
+ - false, without
*/
coapConfig.setString(NetworkConfig.Keys.RESPONSE_MATCHING, "STRICT");
- /*
- https://tools.ietf.org/html/rfc7959#section-2.9.3
- The block size (number of bytes) to use when doing a blockwise transfer. \
- This value serves as the upper limit for block size in blockwise transfers
+ /**
+ https://tools.ietf.org/html/rfc7959#section-2.9.3
+ The block size (number of bytes) to use when doing a blockwise transfer. \
+ This value serves as the upper limit for block size in blockwise transfers
*/
coapConfig.setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE, 1024);
- /*
- The maximum payload size (in bytes) that can be transferred in a
- single message, i.e. without requiring a blockwise transfer.
- NB: this value MUST be adapted to the maximum message size supported by the transport layer.
- In particular, this value cannot exceed the network's MTU if UDP is used as the transport protocol
- DEFAULT_VALUE = 1024
+ /**
+ The maximum payload size (in bytes) that can be transferred in a
+ single message, i.e. without requiring a blockwise transfer.
+ NB: this value MUST be adapted to the maximum message size supported by the transport layer.
+ In particular, this value cannot exceed the network's MTU if UDP is used as the transport protocol
+ DEFAULT_VALUE = 1024
*/
coapConfig.setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE, 1024);
@@ -96,4 +96,4 @@ public class LwM2mNetworkConfig {
return coapConfig;
}
-}
+}
\ No newline at end of file
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java
index 93424b44e5..f0e11aceb4 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java
@@ -94,12 +94,6 @@ public class LwM2mServerListener {
@Override
public void onResponse(Observation observation, Registration registration, ObserveResponse response) {
if (registration != null) {
-// if (observation.getPath().isResource() || observation.getPath().isResourceInstance()) {
-// String msg = String.format("%s: Successful Observation %s.", LOG_LW2M_INFO,
-// observation.getPath());
-// log.warn(msg);
-// service.sendLogsToThingsboard(msg, registration.getId());
-// }
service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(),
registration), response, null);
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java
index 5d6486d9a2..b71de7db1b 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java
@@ -32,6 +32,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseM
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
import java.util.Optional;
+import java.util.UUID;
@Slf4j
public class LwM2mSessionMsgListener implements GenericFutureListener>, SessionMsgListener {
@@ -54,8 +55,8 @@ public class LwM2mSessionMsgListener implements GenericFutureListener= 0 && lwM2MClient != null) {
+ if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) {
if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
- DownlinkRequest request = createRequest (registration, lwM2MClient, typeOper, contentFormat, target,
- targetIdVer, resultIds, params, rpcRequest);
+ DownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target,
+ targetIdVer, resultIds, params, lwm2mClientRpcRequest);
if (request != null) {
try {
- this.sendRequest(registration, lwM2MClient, request, timeoutInMs, rpcRequest);
+ this.sendRequest(registration, lwM2MClient, request, timeoutInMs, lwm2mClientRpcRequest);
} catch (ClientSleepingException e) {
DownlinkRequest finalRequest = request;
long finalTimeoutInMs = timeoutInMs;
- Lwm2mClientRpcRequest finalRpcRequest = rpcRequest;
+ Lwm2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest;
lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest));
} catch (Exception e) {
log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e);
}
- }
- else if (WRITE_UPDATE.name().equals(typeOper.name())) {
- Lwm2mClientRpcRequest rpcRequestClone = (Lwm2mClientRpcRequest) rpcRequest.clone();
- if (rpcRequestClone != null) {
+ } else if (WRITE_UPDATE.name().equals(typeOper.name())) {
+ if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s params is not valid", targetIdVer);
- handler.sentRpcRequest(rpcRequestClone, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
- rpcRequest = null;
+ handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
}
- }
- else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) {
+ } else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) {
+ if (lwm2mClientRpcRequest != null) {
+ String errorMsg = String.format("Path %s object model is absent", targetIdVer);
+ handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
+ }
+ } else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) {
log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer);
- if (rpcRequest != null) {
+ if (lwm2mClientRpcRequest != null) {
ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null";
- handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
+ this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
}
}
- } else if (rpcRequest != null) {
+ } else if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s not found in object version", targetIdVer);
- handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
- }
- } else if (OBSERVE_READ_ALL.name().equals(typeOper.name()) || DISCOVER_All.name().equals(typeOper.name())) {
- Set paths;
- if (OBSERVE_READ_ALL.name().equals(typeOper.name())) {
- Set observations = context.getServer().getObservationService().getObservations(registration);
- paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet());
- } else {
- assert registration != null;
- Link[] objectLinks = registration.getSortedObjectLinks();
- paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet());
- String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO,
- typeOper.name(), paths);
- handler.sendLogsToThingsboard(msg, registration.getId());
+ this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
}
- if (rpcRequest != null) {
- String valueMsg = String.format("Paths - %s", paths);
- handler.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE);
+ } else {
+ switch (typeOper) {
+ case OBSERVE_READ_ALL:
+ case DISCOVER_ALL:
+ Set paths;
+ if (OBSERVE_READ_ALL.name().equals(typeOper.name())) {
+ Set observations = context.getServer().getObservationService().getObservations(registration);
+ paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet());
+ } else {
+ assert registration != null;
+ Link[] objectLinks = registration.getSortedObjectLinks();
+ paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet());
+ }
+ String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO,
+ typeOper.name(), paths);
+ this.handler.sendLogsToThingsboard(msg, registration.getId());
+ if (lwm2mClientRpcRequest != null) {
+ String valueMsg = String.format("Paths - %s", paths);
+ this.handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE);
+ }
+ break;
+ case OBSERVE_CANCEL:
+ case OBSERVE_CANCEL_ALL:
+ int observeCancelCnt = 0;
+ String observeCancelMsg = null;
+ if (OBSERVE_CANCEL.name().equals(typeOper)) {
+ observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target);
+ observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO,
+ OBSERVE_CANCEL.name(), target, observeCancelCnt);
+ } else {
+ observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration);
+ observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO,
+ OBSERVE_CANCEL.name(), observeCancelCnt);
+ }
+ this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest);
+ break;
+ // lwm2mClientRpcRequest != null
+ case FW_UPDATE:
+ this.handler.getInfoFirmwareUpdate(lwM2MClient, lwm2mClientRpcRequest);
+ break;
}
- } else if (OBSERVE_CANCEL.name().equals(typeOper.name())) {
- int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration);
- String observeCancelMsgAll = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO,
- OBSERVE_CANCEL.name(), observeCancelCnt);
- this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsgAll, rpcRequest);
}
} catch (Exception e) {
String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR,
typeOper.name(), e.getMessage());
handler.sendLogsToThingsboard(msg, registration.getId());
- if (rpcRequest != null) {
+ if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage());
- handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
+ handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
}
}
}
- private DownlinkRequest createRequest (Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper,
- ContentFormat contentFormat, String target, String targetIdVer,
- LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) {
+ private DownlinkRequest createRequest(Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper,
+ ContentFormat contentFormat, String target, String targetIdVer,
+ LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) {
DownlinkRequest request = null;
switch (typeOper) {
case READ:
@@ -212,7 +235,7 @@ public class LwM2mTransportRequest {
request = new DiscoverRequest(target);
break;
case OBSERVE:
- String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer);
+ String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer);
log.warn(msg);
if (resultIds.isResource()) {
Set observations = context.getServer().getObservationService().getObservations(registration);
@@ -228,23 +251,14 @@ public class LwM2mTransportRequest {
request = new ObserveRequest(contentFormat, resultIds.getObjectId());
}
break;
- case OBSERVE_CANCEL:
- /*
- lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
- At server side this will not remove the observation from the observation store, to do it you need to use
- {@code ObservationService#cancelObservation()}
- */
- int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target);
- String observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO,
- OBSERVE_CANCEL.name(), target, observeCancelCnt);
- this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, rpcRequest);
- break;
case EXECUTE:
- ResourceModel resourceModelExe = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
- if (params != null && !resourceModelExe.multiple) {
- request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModelExe.type, ResourceModel.Type.STRING, resultIds));
- } else {
- request = new ExecuteRequest(target);
+ ResourceModel resourceModelExecute = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
+ if (resourceModelExecute != null) {
+ if (params != null && !resourceModelExecute.multiple) {
+ request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModelExecute.type, ResourceModel.Type.STRING, resultIds));
+ } else {
+ request = new ExecuteRequest(target);
+ }
}
break;
case WRITE_REPLACE:
@@ -255,10 +269,12 @@ public class LwM2mTransportRequest {
* JSON, TEXT;
**/
ResourceModel resourceModelWrite = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
- contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat);
- request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(),
- resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type,
- registration, rpcRequest);
+ if (resourceModelWrite != null) {
+ contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat);
+ request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(),
+ resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type,
+ registration, rpcRequest);
+ }
break;
case WRITE_UPDATE:
if (resultIds.isResource()) {
@@ -297,7 +313,7 @@ public class LwM2mTransportRequest {
}
break;
case WRITE_ATTRIBUTES:
- request = createWriteAttributeRequest(target, params);
+ request = createWriteAttributeRequest(target, params, this.handler);
break;
case DELETE:
request = new DeleteRequest(target);
@@ -333,7 +349,7 @@ public class LwM2mTransportRequest {
}
/** Not Found */
if (rpcRequest != null) {
- handler.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
}
/** Not Found
set setClient_fw_info... = empty
@@ -375,7 +391,7 @@ public class LwM2mTransportRequest {
handler.sendLogsToThingsboard(msg, registration.getId());
log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString());
if (rpcRequest != null) {
- handler.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR);
+ handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR);
}
});
}
@@ -421,7 +437,7 @@ public class LwM2mTransportRequest {
log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString());
if (rpcRequest != null) {
String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value);
- handler.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
+ handler.sentRpcResponse(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
}
return null;
}
@@ -452,68 +468,92 @@ public class LwM2mTransportRequest {
if (response instanceof ReadResponse) {
handler.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest);
} else if (response instanceof DeleteResponse) {
- log.warn("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response);
+ log.warn("11) [{}] Path [{}] DeleteResponse", pathIdVer, response);
+ if (rpcRequest != null) {
+ rpcRequest.setInfoMsg(null);
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), null, null);
+ }
} else if (response instanceof DiscoverResponse) {
- String discoverValue = Link.serialize(((DiscoverResponse)response).getObjectLinks());
+ String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks());
msgLog = String.format("%s: type operation: %s path: %s value: %s",
LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue);
handler.sendLogsToThingsboard(msgLog, registration.getId());
log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response);
if (rpcRequest != null) {
- handler.sentRpcRequest(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE);
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE);
}
} else if (response instanceof ExecuteResponse) {
- log.warn("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response);
+ msgLog = String.format("%s: type operation: %s path: %s",
+ LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString());
+ log.warn("9) [{}] ", msgLog);
+ handler.sendLogsToThingsboard(msgLog, registration.getId());
+ if (rpcRequest != null) {
+ msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg());
+ rpcRequest.setInfoMsg(msgLog);
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), path, LOG_LW2M_INFO);
+ }
+
} else if (response instanceof WriteAttributesResponse) {
- log.warn("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response);
+ msgLog = String.format("%s: type operation: %s path: %s value: %s",
+ LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString());
+ handler.sendLogsToThingsboard(msgLog, registration.getId());
+ log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response);
+ if (rpcRequest != null) {
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE);
+ }
} else if (response instanceof WriteResponse) {
- log.warn("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response);
- this.infoWriteResponse(registration, response, request);
+ msgLog = String.format("Type operation: Write path: %s", pathIdVer);
+ log.warn("10) [{}] response: [{}]", msgLog, response);
+ this.infoWriteResponse(registration, response, request, rpcRequest);
handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request);
}
- if (rpcRequest != null) {
- if (response instanceof ExecuteResponse
- || response instanceof WriteAttributesResponse
- || response instanceof DeleteResponse) {
- rpcRequest.setInfoMsg(null);
- handler.sentRpcRequest(rpcRequest, response.getCode().getName(), null, null);
- } else if (response instanceof WriteResponse) {
- handler.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO);
- }
- }
}
- private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request) {
+ private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
try {
LwM2mNode node = ((WriteRequest) request).getNode();
- String msg;
+ String msg = null;
Object value;
- LwM2mSingleResource singleResource = (LwM2mSingleResource) node;
- if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) {
- int valueLength;
- if (singleResource.getType() == ResourceModel.Type.STRING) {
- valueLength = ((String) singleResource.getValue()).length();
- value = ((String) singleResource.getValue())
- .substring(Math.min(valueLength, config.getLogMaxLength()));
+ if (node instanceof LwM2mObject) {
+ msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s",
+ LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObject) node).toString());
+ } else if (node instanceof LwM2mObjectInstance) {
+ msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s",
+ LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObjectInstance) node).prettyPrint());
+ } else if (node instanceof LwM2mSingleResource) {
+ LwM2mSingleResource singleResource = (LwM2mSingleResource) node;
+ if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) {
+ int valueLength;
+ if (singleResource.getType() == ResourceModel.Type.STRING) {
+ valueLength = ((String) singleResource.getValue()).length();
+ value = ((String) singleResource.getValue())
+ .substring(Math.min(valueLength, config.getLogMaxLength())).trim();
+ } else {
+ valueLength = ((byte[]) singleResource.getValue()).length;
+ value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()),
+ Math.min(valueLength, config.getLogMaxLength()))).trim();
+ }
+ value = valueLength > config.getLogMaxLength() ? value + "..." : value;
+ msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s",
+ LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value);
} else {
- valueLength = ((byte[]) singleResource.getValue()).length;
- value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()),
- Math.min(valueLength, config.getLogMaxLength())));
+ value = this.converter.convertValue(singleResource.getValue(),
+ singleResource.getType(), ResourceModel.Type.STRING, request.getPath());
+ msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s",
+ LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value);
}
- value = valueLength > config.getLogMaxLength() ? value + "..." : value;
- msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s",
- LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value);
- } else {
- value = this.converter.convertValue(singleResource.getValue(),
- singleResource.getType(), ResourceModel.Type.STRING, request.getPath());
- msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s",
- LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value);
}
if (msg != null) {
handler.sendLogsToThingsboard(msg, registration.getId());
if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) {
this.afterWriteSuccessFwSwUpdate(registration, request);
+ if (rpcRequest != null) {
+ rpcRequest.setInfoMsg(msg);
+ }
+ }
+ else if (rpcRequest != null) {
+ handler.sentRpcResponse(rpcRequest, response.getCode().getName(), msg, LOG_LW2M_INFO);
}
}
} catch (Exception e) {
@@ -530,11 +570,11 @@ public class LwM2mTransportRequest {
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) {
lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name());
- lwM2MClient.getFwUpdate().sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
+ lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
}
if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) {
lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name());
- lwM2MClient.getSwUpdate().sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
+ lwM2MClient.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
}
}
@@ -545,21 +585,21 @@ public class LwM2mTransportRequest {
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) {
lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name());
- lwM2MClient.getFwUpdate().sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
+ lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
}
if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) {
lwM2MClient.getSwUpdate().setStateUpdate(FAILED.name());
- lwM2MClient.getSwUpdate().sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
+ lwM2MClient.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
}
}
private void afterExecuteFwSwUpdateError(Registration registration, DownlinkRequest request, String msgError) {
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) {
- lwM2MClient.getFwUpdate().sendLogs(handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError);
+ lwM2MClient.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError);
}
if (request.getPath().toString().equals(SW_INSTALL_ID) && lwM2MClient.getSwUpdate() != null) {
- lwM2MClient.getSwUpdate().sendLogs(handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError);
+ lwM2MClient.getSwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError);
}
}
@@ -568,7 +608,7 @@ public class LwM2mTransportRequest {
log.warn("[{}]", observeCancelMsg);
if (rpcRequest != null) {
rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt));
- handler.sentRpcRequest(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO);
+ handler.sentRpcResponse(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO);
}
}
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java
index fff35ea855..d31883015e 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java
@@ -53,6 +53,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V;
@@ -64,6 +66,13 @@ public class LwM2mTransportServerHelper {
private final LwM2mTransportContext context;
private final LwM2MJsonAdaptor adaptor;
+ private final AtomicInteger atomicTs = new AtomicInteger(0);
+
+
+ public long getTS() {
+ int addTs = atomicTs.getAndIncrement() >= 1000 ? atomicTs.getAndSet(0) : atomicTs.get();
+ return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) * 1000L + addTs;
+ }
/**
* send to Thingsboard Attribute || Telemetry
@@ -96,7 +105,7 @@ public class LwM2mTransportServerHelper {
public void sendParametersOnThingsboardTelemetry(List result, SessionInfoProto sessionInfo) {
PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder();
TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder();
- builder.setTs(System.currentTimeMillis());
+ builder.setTs(this.getTS());
builder.addAllKv(result);
request.addTsKvList(builder.build());
PostTelemetryMsg postTelemetryMsg = request.build();
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java
index c84b4a52b2..adf9e07bc4 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java
@@ -43,7 +43,10 @@ import org.eclipse.leshan.server.registration.Registration;
import org.nustaq.serialization.FSTConfiguration;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
-import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;
+import org.thingsboard.server.common.data.ota.OtaPackageKey;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
+import org.thingsboard.server.common.data.ota.OtaPackageUtil;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
@@ -61,9 +64,12 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION;
+import static org.eclipse.leshan.core.attributes.Attribute.GREATER_THAN;
+import static org.eclipse.leshan.core.attributes.Attribute.LESSER_THAN;
import static org.eclipse.leshan.core.attributes.Attribute.MAXIMUM_PERIOD;
import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD;
import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
+import static org.eclipse.leshan.core.attributes.Attribute.STEP;
import static org.eclipse.leshan.core.model.ResourceModel.Type.BOOLEAN;
import static org.eclipse.leshan.core.model.ResourceModel.Type.FLOAT;
import static org.eclipse.leshan.core.model.ResourceModel.Type.INTEGER;
@@ -71,12 +77,12 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING;
import static org.eclipse.leshan.core.model.ResourceModel.Type.TIME;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADING;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.FAILED;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATED;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.VERIFIED;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
@@ -104,8 +110,7 @@ public class LwM2mTransportUtil {
public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms
- public static final String
- LOG_LW2M_TELEMETRY = "LwM2MLog";
+ public static final String LOG_LW2M_TELEMETRY = "logLwm2m";
public static final String LOG_LW2M_INFO = "info";
public static final String LOG_LW2M_ERROR = "error";
public static final String LOG_LW2M_WARN = "warn";
@@ -117,7 +122,24 @@ public class LwM2mTransportUtil {
public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized";
public static final String LWM2M_VERSION_DEFAULT = "1.0";
- // FirmWare
+ // RPC
+ public static final String TYPE_OPER_KEY = "typeOper";
+ public static final String TARGET_ID_VER_KEY = "targetIdVer";
+ public static final String KEY_NAME_KEY = "key";
+ public static final String VALUE_KEY = "value";
+ public static final String PARAMS_KEY = "params";
+ public static final String SEPARATOR_KEY = ":";
+ public static final String FINISH_VALUE_KEY = ",";
+ public static final String START_JSON_KEY = "{";
+ public static final String FINISH_JSON_KEY = "}";
+ // public static final String contentFormatNameKey = "contentFormatName";
+ public static final String INFO_KEY = "info";
+ // public static final String TIME_OUT_IN_MS = "timeOutInMs";
+ public static final String RESULT_KEY = "result";
+ public static final String ERROR_KEY = "error";
+ public static final String METHOD_KEY = "methodName";
+
+ // Firmware
public static final String FW_UPDATE = "Firmware update";
public static final Integer FW_ID = 5;
// Package W
@@ -133,7 +155,7 @@ public class LwM2mTransportUtil {
// Update E
public static final String FW_UPDATE_ID = "/5/0/2";
- // SoftWare
+ // Software
public static final String SW_UPDATE = "Software update";
public static final Integer SW_ID = 9;
// Package W
@@ -182,20 +204,21 @@ public class LwM2mTransportUtil {
*/
READ(0, "Read"),
DISCOVER(1, "Discover"),
- DISCOVER_All(2, "DiscoverAll"),
+ DISCOVER_ALL(2, "DiscoverAll"),
OBSERVE_READ_ALL(3, "ObserveReadAll"),
/**
* POST
*/
OBSERVE(4, "Observe"),
OBSERVE_CANCEL(5, "ObserveCancel"),
- EXECUTE(6, "Execute"),
+ OBSERVE_CANCEL_ALL(6, "ObserveCancelAll"),
+ EXECUTE(7, "Execute"),
/**
* Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see
* section 5.3.3 of the LW M2M spec).
* if all resources are to be replaced
*/
- WRITE_REPLACE(7, "WriteReplace"),
+ WRITE_REPLACE(8, "WriteReplace"),
/*
PUT
*/
@@ -204,18 +227,17 @@ public class LwM2mTransportUtil {
* 5.3.3 of the LW M2M spec).
* if this is a partial update request
*/
- WRITE_UPDATE(8, "WriteUpdate"),
- WRITE_ATTRIBUTES(9, "WriteAttributes"),
- DELETE(10, "Delete"),
+ WRITE_UPDATE(9, "WriteUpdate"),
+ WRITE_ATTRIBUTES(10, "WriteAttributes"),
+ DELETE(11, "Delete"),
// only for RPC
- FW_READ_INFO(11, "FirmwareReadInfo"),
- FW_UPDATE(12, "FirmwareUpdate"),
- FW_UPDATE_URL(14, "FirmwareUpdateUrl"),
- SW_READ_INFO(15, "SoftwareReadInfo"),
- SW_UPDATE(16, "SoftwareUpdate"),
- SW_UPDATE_URL(17, "SoftwareUpdateUrl"),
- SW_UNINSTALL(18, "SoftwareUninstall");
+ FW_UPDATE(12,"FirmwareUpdate");
+// FW_READ_INFO(12, "FirmwareReadInfo"),
+
+// SW_READ_INFO(15, "SoftwareReadInfo"),
+// SW_UPDATE(16, "SoftwareUpdate"),
+// SW_UNINSTALL(18, "SoftwareUninstall");
public int code;
public String type;
@@ -333,7 +355,7 @@ public class LwM2mTransportUtil {
* FirmwareUpdateStatus {
* DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
*/
- public static FirmwareUpdateStatus EqualsFwSateToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) {
+ public static OtaPackageUpdateStatus EqualsFwSateToFirmwareUpdateStatus(StateFw stateFw, UpdateResultFw updateResultFw) {
switch (updateResultFw) {
case INITIAL:
switch (stateFw) {
@@ -479,7 +501,7 @@ public class LwM2mTransportUtil {
* FirmwareUpdateStatus {
* DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
*/
- public static FirmwareUpdateStatus EqualsSwSateToFirmwareUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) {
+ public static OtaPackageUpdateStatus EqualsSwSateToFirmwareUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) {
switch (updateResultSw) {
case INITIAL:
switch (updateStateSw) {
@@ -817,26 +839,29 @@ public class LwM2mTransportUtil {
* Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60");
* Attribute [] attrs = {gt, st};
*/
- public static DownlinkRequest createWriteAttributeRequest(String target, Object params) {
- AttributeSet attrSet = new AttributeSet(createWriteAttributes(params));
+ public static DownlinkRequest createWriteAttributeRequest(String target, Object params, DefaultLwM2MTransportMsgHandler serviceImpl) {
+ AttributeSet attrSet = new AttributeSet(createWriteAttributes(params, serviceImpl, target));
return attrSet.getAttributes().size() > 0 ? new WriteAttributesRequest(target, attrSet) : null;
}
- private static Attribute[] createWriteAttributes(Object params) {
+ private static Attribute[] createWriteAttributes(Object params, DefaultLwM2MTransportMsgHandler serviceImpl, String target) {
List attributeLists = new ArrayList<>();
ObjectMapper oMapper = new ObjectMapper();
Map map = oMapper.convertValue(params, ConcurrentHashMap.class);
map.forEach((k, v) -> {
- if (!v.toString().isEmpty() || (v.toString().isEmpty() && OBJECT_VERSION.equals(k))) {
- attributeLists.add(new Attribute(k,
- (DIMENSION.equals(k) || MINIMUM_PERIOD.equals(k) || MAXIMUM_PERIOD.equals(k)) ?
- ((Double) v).longValue() : v));
+ if (StringUtils.trimToNull(v.toString()) != null) {
+ Object attrValue = convertWriteAttributes(k, v, serviceImpl, target);
+ if (attrValue != null) {
+ Attribute attribute = createAttribute(k, attrValue);
+ if (attribute != null) {
+ attributeLists.add(new Attribute(k, attrValue));
+ }
+ }
}
});
return attributeLists.toArray(Attribute[]::new);
}
-
public static Set convertJsonArrayToSet(JsonArray jsonArray) {
List attributeListOld = new Gson().fromJson(jsonArray, new TypeToken>() {
}.getType());
@@ -863,4 +888,60 @@ public class LwM2mTransportUtil {
return null;
}
}
+
+ public static LwM2mTypeOper setValidTypeOper(String typeOper) {
+ try {
+ return LwM2mTransportUtil.LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static Object convertWriteAttributes(String type, Object value, DefaultLwM2MTransportMsgHandler serviceImpl, String target) {
+ switch (type) {
+ /** Integer [0:255]; */
+ case DIMENSION:
+ Long dim = (Long) serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), INTEGER, new LwM2mPath(target));
+ return dim >= 0 && dim <= 255 ? dim : null;
+ /**String;*/
+ case OBJECT_VERSION:
+ return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), STRING, new LwM2mPath(target));
+ /**INTEGER */
+ case MINIMUM_PERIOD:
+ case MAXIMUM_PERIOD:
+ return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), INTEGER, new LwM2mPath(target));
+ /**Float; */
+ case GREATER_THAN:
+ case LESSER_THAN:
+ case STEP:
+ if (value.getClass().getSimpleName().equals("String") ) {
+ value = Double.valueOf((String) value);
+ }
+ return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), FLOAT, new LwM2mPath(target));
+ default:
+ return null;
+ }
+ }
+
+ private static Attribute createAttribute(String key, Object attrValue) {
+ try {
+ return new Attribute(key, attrValue);
+ } catch (Exception e) {
+ log.error("CreateAttribute, not valid parameter key: [{}], attrValue: [{}], error: [{}]", key, attrValue, e.getMessage());
+ return null;
+ }
+ }
+
+ public static boolean isFwSwWords (String pathName) {
+ return OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.SIZE).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
+ || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.SIZE).equals(pathName);
+ }
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java
index d3f1fb4343..a6a1fadbf3 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java
@@ -31,8 +31,8 @@ import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
@@ -117,12 +117,11 @@ public class LwM2mClient implements Cloneable {
this.pendingReadRequests = new CopyOnWriteArrayList<>();
this.resources = new ConcurrentHashMap<>();
this.profileId = profileId;
- this.sessionId = sessionId;
this.init = false;
this.queuedRequests = new ConcurrentLinkedQueue<>();
- this.fwUpdate = new LwM2mFwSwUpdate(this, FirmwareType.FIRMWARE);
- this.swUpdate = new LwM2mFwSwUpdate(this, FirmwareType.SOFTWARE);
+ this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE);
+ this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE);
if (this.credentials != null && this.credentials.hasDeviceInfo()) {
this.session = createSession(nodeId, sessionId, credentials);
this.deviceId = new UUID(session.getDeviceIdMSB(), session.getDeviceIdLSB());
@@ -194,17 +193,31 @@ public class LwM2mClient implements Cloneable {
public Object getResourceValue(String pathRezIdVer, String pathRezId) {
String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer;
if (this.resources.get(pathRez) != null) {
- return this.resources.get(pathRez).getLwM2mResource().isMultiInstances() ?
+ return this.resources.get(pathRez).getLwM2mResource().isMultiInstances() ?
this.resources.get(pathRez).getLwM2mResource().getValues() :
this.resources.get(pathRez).getLwM2mResource().getValue();
}
return null;
}
- public Object getResourceName (String pathRezIdVer, String pathRezId) {
+ public Object getResourceNameByRezId(String pathRezIdVer, String pathRezId) {
String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer;
if (this.resources.get(pathRez) != null) {
- return this.resources.get(pathRez).getResourceModel().name;
+ return this.resources.get(pathRez).getResourceModel().name;
+ }
+ return null;
+ }
+
+ public String getRezIdByResourceNameAndObjectInstanceId(String resourceName, String pathObjectInstanceIdVer, LwM2mModelProvider modelProvider) {
+ LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathObjectInstanceIdVer));
+ if (pathIds.isObjectInstance()) {
+ Set rezIds = modelProvider.getObjectModel(registration)
+ .getObjectModel(pathIds.getObjectId()).resources.entrySet()
+ .stream()
+ .filter(map -> resourceName.equals(map.getValue().name))
+ .map(map -> map.getKey())
+ .collect(Collectors.toSet());
+ return rezIds.size() > 0 ? String.valueOf(rezIds.stream().findFirst().get()) : null;
}
return null;
}
@@ -225,11 +238,11 @@ public class LwM2mClient implements Cloneable {
.getObjectModel(pathIds.getObjectId()) : null;
}
- public String objectToString (LwM2mObject lwM2mObject, LwM2mValueConverterImpl converter, String pathIdVer) {
+ public String objectToString(LwM2mObject lwM2mObject, LwM2mValueConverterImpl converter, String pathIdVer) {
StringBuilder builder = new StringBuilder();
builder.append("LwM2mObject [id=").append(lwM2mObject.getId()).append(", instances={");
lwM2mObject.getInstances().forEach((instId, inst) -> {
- builder.append(instId).append("=").append(this.instanceToString(inst, converter, pathIdVer)).append(", ");
+ builder.append(instId).append("=").append(this.instanceToString(inst, converter, pathIdVer)).append(", ");
});
int startInd = builder.lastIndexOf(", ");
if (startInd > 0) {
@@ -238,11 +251,12 @@ public class LwM2mClient implements Cloneable {
builder.append("}]");
return builder.toString();
}
- public String instanceToString (LwM2mObjectInstance objectInstance, LwM2mValueConverterImpl converter, String pathIdVer) {
+
+ public String instanceToString(LwM2mObjectInstance objectInstance, LwM2mValueConverterImpl converter, String pathIdVer) {
StringBuilder builder = new StringBuilder();
builder.append("LwM2mObjectInstance [id=").append(objectInstance.getId()).append(", resources={");
objectInstance.getResources().forEach((resId, res) -> {
- builder.append(resId).append("=").append(this.resourceToString (res, converter, pathIdVer)).append(", ");
+ builder.append(resId).append("=").append(this.resourceToString(res, converter, pathIdVer)).append(", ");
});
int startInd = builder.lastIndexOf(", ");
if (startInd > 0) {
@@ -252,12 +266,11 @@ public class LwM2mClient implements Cloneable {
return builder.toString();
}
- public String resourceToString (LwM2mResource lwM2mResource, LwM2mValueConverterImpl converter, String pathIdVer) {
+ public String resourceToString(LwM2mResource lwM2mResource, LwM2mValueConverterImpl converter, String pathIdVer) {
if (!OPAQUE.equals(lwM2mResource.getType())) {
return lwM2mResource.isMultiInstances() ? ((LwM2mMultipleResource) lwM2mResource).toString() :
((LwM2mSingleResource) lwM2mResource).toString();
- }
- else {
+ } else {
return String.format("LwM2mSingleResource [id=%s, value=%s, type=%s]", lwM2mResource.getId(),
converter.convertValue(lwM2mResource.getValue(),
OPAQUE, STRING, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))), lwM2mResource.getType().name());
@@ -275,7 +288,8 @@ public class LwM2mClient implements Cloneable {
resources.add(LwM2mSingleResource.newResource(resId, converter.convertValue(params,
equalsResourceTypeGetSimpleName(params), resourceModel.type, pathIds), resourceModel.type));
- }});
+ }
+ });
return resources;
}
@@ -291,7 +305,8 @@ public class LwM2mClient implements Cloneable {
resources.add(LwM2mSingleResource.newResource(resId,
converter.convertValue(value, equalsResourceTypeGetSimpleName(value), resourceModel.type, pathIds), resourceModel.type));
- }});
+ }
+ });
return resources;
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java
index 554a6e650c..bb3e97b7e4 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java
@@ -35,8 +35,6 @@ public interface LwM2mClientContext {
LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo);
- LwM2mClient getClient(UUID sessionId);
-
LwM2mClient getOrRegister(Registration registration);
LwM2mClient registerOrUpdate(Registration registration);
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java
index 0a49ea82b2..8674516e85 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java
@@ -83,13 +83,17 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
@Override
public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) {
- return getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
- }
-
- @Override
- public LwM2mClient getClient(UUID sessionId) {
- //TODO: refactor this to search by sessionId efficiently.
- return lwM2mClientsByEndpoint.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get();
+ LwM2mClient lwM2mClient = lwM2mClientsByEndpoint.values().stream().filter(c ->
+ (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()))
+ .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB())))
+
+ ).findAny().get();
+ if (lwM2mClient == null) {
+ log.warn("Device TimeOut? lwM2mClient is null.");
+ log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size());
+ log.error("", new RuntimeException());
+ }
+ return lwM2mClient;
}
@Override
@@ -118,7 +122,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
securityInfo.getDeviceProfile().getUuidId() : null;
// TODO: for tests bug.
if (profileUuid== null) {
- log.warn("input parameters toClientProfile if the result is null: [{}]", securityInfo.getDeviceProfile());
+ log.trace("input parameters toClientProfile if the result is null: [{}]", securityInfo.getDeviceProfile());
}
LwM2mClient client;
if (securityInfo.getSecurityInfo() != null) {
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java
index 499d48a794..e940061c66 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java
@@ -20,8 +20,8 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.leshan.core.request.ContentFormat;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportRequest;
@@ -32,11 +32,12 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
-import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;
-import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE;
-import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING;
-import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey;
+import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE;
+import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
+import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
+import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
+import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey;
+import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID;
@@ -97,14 +98,17 @@ public class LwM2mFwSwUpdate {
@Getter
@Setter
private volatile boolean infoFwSwUpdate = false;
- private final FirmwareType type;
+ private final OtaPackageType type;
@Getter
LwM2mClient lwM2MClient;
@Getter
@Setter
private final List pendingInfoRequestsStart;
+ @Getter
+ @Setter
+ private volatile Lwm2mClientRpcRequest rpcRequest;
- public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, FirmwareType type) {
+ public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) {
this.lwM2MClient = lwM2MClient;
this.pendingInfoRequestsStart = new CopyOnWriteArrayList<>();
this.type = type;
@@ -139,7 +143,7 @@ public class LwM2mFwSwUpdate {
}
if (this.pendingInfoRequestsStart.size() == 0) {
this.infoFwSwUpdate = false;
- if (!FirmwareUpdateStatus.DOWNLOADING.name().equals(this.stateUpdate)) {
+ if (!OtaPackageUpdateStatus.DOWNLOADING.name().equals(this.stateUpdate)) {
boolean conditionalStart = this.type.equals(FIRMWARE) ? this.conditionalFwUpdateStart() :
this.conditionalSwUpdateStart();
if (conditionalStart) {
@@ -153,16 +157,30 @@ public class LwM2mFwSwUpdate {
* Send FsSw to Lwm2mClient:
* before operation Write: fw_state = DOWNLOADING
*/
- private void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) {
- this.stateUpdate = FirmwareUpdateStatus.DOWNLOADING.name();
-// this.observeStateUpdate();
- this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
- int chunkSize = 0;
- int chunk = 0;
- byte[] firmwareChunk = handler.firmwareDataCache.get(this.currentId.toString(), chunkSize, chunk);
- String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration());
- request.sendAllRequest(lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(),
- firmwareChunk, handler.config.getTimeout(), null);
+ public void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) {
+ if (this.currentId != null) {
+ this.stateUpdate = OtaPackageUpdateStatus.DOWNLOADING.name();
+ this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
+ int chunkSize = 0;
+ int chunk = 0;
+ byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk);
+ String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration());
+ String fwMsg = String.format("%s: Start type operation %s paths: %s", LOG_LW2M_INFO,
+ LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), FW_PACKAGE_ID);
+ handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId());
+ log.warn("8) Start firmware Update. Send save to: [{}] ver: [{}] path: [{}]", this.lwM2MClient.getDeviceName(), this.currentVersion, targetIdVer);
+ request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(),
+ firmwareChunk, handler.config.getTimeout(), this.rpcRequest);
+ }
+ else {
+ String msgError = "FirmWareId is null.";
+ log.warn("6) [{}]", msgError);
+ if (this.rpcRequest != null) {
+ handler.sentRpcResponse(this.rpcRequest, CONTENT.name(), msgError, LOG_LW2M_ERROR);
+ }
+ log.error (msgError);
+ this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
+ }
}
public void sendLogs(DefaultLwM2MTransportMsgHandler handler, String typeOper, String typeInfo, String msgError) {
@@ -185,17 +203,16 @@ public class LwM2mFwSwUpdate {
this.setStateUpdate(UPDATING.name());
this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null);
request.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(),
- null, 0, null);
+ null, 0, this.rpcRequest);
}
-
/**
* Firmware start:
- * -- Если Update Result -errors (более 1) - Это означает что пред. апдейт не прошел.
- * - Запускаем апдейт в независимости от состяния прошивки и ее версии.
- * -- Если Update Result - не errors (менее или равно 1) и ver не пустой - Это означает что пред. апдейт прошел.
- * -- Если Update Result - не errors и ver пустой - Это означает что апдейта еще не было.
- * - Проверяем поменялась ли версия и запускаем новый апдейт.
+ * -- If the result of the update - errors (more than 1) - This means that the previous. the update failed.
+ * - We launch the update regardless of the state of the firmware and its version.
+ * -- If the result of the update is not errors (equal to 1 or 0) and ver is not empty - This means that before the update has passed.
+ * -- If the result of the update is not errors and is empty - This means that there has not been an update yet.
+ * - Check if the version has changed and launch a new update.
*/
private boolean conditionalFwUpdateStart() {
Long updateResultFw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
@@ -241,12 +258,12 @@ public class LwM2mFwSwUpdate {
/**
* Software start
- * -- Если Update Result -errors (равно и более 50) - Это означает что пред. апдейт не прошел.
- * * - Запускаем апдейт в независимости от состяния прошивки и ее версии.
- * -- Если Update Result - не errors (менее 50) и ver не пустой - Это означает что пред. апдейт прошел.
- * -- Если Update Result - не errors и ver пустой - Это означает что апдейта еще не было или пред. апдейт UnInstall
- * -- Если Update Result - не errors и ver не пустой - Это означает что пред. апдейт UnInstall
- * - Проверяем поменялась ли версия и запускаем новый апдейт.
+ * - If Update Result -errors (equal or more than 50) - This means that the previous. the update failed.
+ * * - We launch the update regardless of the state of the firmware and its version.
+ * - If Update Result is not errors (less than 50) and ver is not empty - This means that before. the update has passed.
+ * - If Update Result is not errors and ver is empty - This means that there was no update yet or before. UnInstall update
+ * - If Update Result is not errors and ver is not empty - This means that before unInstall update
+ * * - Check if the version has changed and launch a new update.
*/
private boolean conditionalSwUpdateStart() {
Long updateResultSw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
@@ -286,12 +303,12 @@ public class LwM2mFwSwUpdate {
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
String value = FIRMWARE.equals(this.type) ? LwM2mTransportUtil.UpdateResultFw.fromUpdateResultFwByCode(updateResult.intValue()).type :
LwM2mTransportUtil.UpdateResultSw.fromUpdateResultSwByCode(updateResult.intValue()).type;
- String key = splitCamelCaseString((String) this.lwM2MClient.getResourceName(null, this.pathResultId));
+ String key = splitCamelCaseString((String) this.lwM2MClient.getResourceNameByRezId(null, this.pathResultId));
if (success) {
- this.stateUpdate = FirmwareUpdateStatus.UPDATED.name();
+ this.stateUpdate = OtaPackageUpdateStatus.UPDATED.name();
this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null);
} else {
- this.stateUpdate = FirmwareUpdateStatus.FAILED.name();
+ this.stateUpdate = OtaPackageUpdateStatus.FAILED.name();
this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_ERROR, value);
}
handler.helper.sendParametersOnThingsboardTelemetry(
@@ -348,7 +365,7 @@ public class LwM2mFwSwUpdate {
this.pathResultId, this.lwM2MClient.getRegistration()));
this.pendingInfoRequestsStart.forEach(pathIdVer -> {
request.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(),
- null, 0, null);
+ null, 0, this.rpcRequest);
});
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java
index 77a26b4755..d71c6b27f6 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java
@@ -15,94 +15,94 @@
*/
package org.thingsboard.server.transport.lwm2m.server.client;
+import com.google.gson.Gson;
import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
-import org.eclipse.leshan.core.request.ContentFormat;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.server.registration.Registration;
import org.thingsboard.server.gen.transport.TransportProtos;
-import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
-import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
+import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
+import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeoutException;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.ERROR_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FINISH_JSON_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FINISH_VALUE_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.INFO_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.KEY_NAME_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.METHOD_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.PARAMS_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESULT_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SEPARATOR_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.START_JSON_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.TARGET_ID_VER_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.VALUE_KEY;
+import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validPathIdVer;
@Slf4j
@Data
public class Lwm2mClientRpcRequest {
- public final String targetIdVerKey = "targetIdVer";
- public final String keyNameKey = "key";
- public final String typeOperKey = "typeOper";
- public final String contentFormatNameKey = "contentFormatName";
- public final String valueKey = "value";
- public final String infoKey = "info";
- public final String paramsKey = "params";
- public final String timeoutInMsKey = "timeOutInMs";
- public final String resultKey = "result";
- public final String errorKey = "error";
- public final String methodKey = "methodName";
+
+ private Registration registration;
+ private TransportProtos.SessionInfoProto sessionInfo;
+ private String bodyParams;
+ private int requestId;
private LwM2mTypeOper typeOper;
+ private String key;
private String targetIdVer;
- private String contentFormatName;
- private long timeoutInMs;
private Object value;
- private ConcurrentHashMap params;
- private SessionInfoProto sessionInfo;
- private int requestId;
+ private Map params;
+
private String errorMsg;
private String valueMsg;
private String infoMsg;
private String responseCode;
- public void setValidTypeOper(String typeOper) {
- try {
- this.typeOper = LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper);
- } catch (Exception e) {
- this.errorMsg = this.methodKey + " - " + typeOper + " is not valid.";
- }
+ public Lwm2mClientRpcRequest() {
}
- public void setValidContentFormatName(JsonObject rpcRequest) {
- try {
- if (ContentFormat.fromName(rpcRequest.get(this.contentFormatNameKey).getAsString()) != null) {
- this.contentFormatName = rpcRequest.get(this.contentFormatNameKey).getAsString();
- } else {
- this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid.";
- }
- } catch (Exception e) {
- this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid.";
+ public Lwm2mClientRpcRequest(LwM2mTypeOper lwM2mTypeOper, String bodyParams, int requestId,
+ TransportProtos.SessionInfoProto sessionInfo, Registration registration, DefaultLwM2MTransportMsgHandler handler) {
+ this.registration = registration;
+ this.sessionInfo = sessionInfo;
+ this.requestId = requestId;
+ if (lwM2mTypeOper != null) {
+ this.typeOper = lwM2mTypeOper;
+ } else {
+ this.errorMsg = METHOD_KEY + " - " + typeOper + " is not valid.";
}
- }
-
- public void setValidTargetIdVerKey(JsonObject rpcRequest, Registration registration) {
- if (rpcRequest.has(this.targetIdVerKey)) {
- String targetIdVerStr = rpcRequest.get(targetIdVerKey).getAsString();
- // targetIdVer without ver - ok
- try {
- // targetIdVer with/without ver - ok
- this.targetIdVer = validPathIdVer(targetIdVerStr, registration);
- if (this.targetIdVer != null) {
- this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer);
- }
- } catch (Exception e) {
- if (this.targetIdVer == null) {
- this.errorMsg = this.targetIdVerKey + " - " + targetIdVerStr + " is not valid.";
- }
- }
+ if (this.errorMsg == null && !bodyParams.equals("null")) {
+ this.bodyParams = bodyParams;
+ this.init(handler);
}
}
public TransportProtos.ToDeviceRpcResponseMsg getDeviceRpcResponseResultMsg() {
JsonObject payloadResp = new JsonObject();
- payloadResp.addProperty(this.resultKey, this.responseCode);
+ payloadResp.addProperty(RESULT_KEY, this.responseCode);
if (this.errorMsg != null) {
- payloadResp.addProperty(this.errorKey, this.errorMsg);
+ payloadResp.addProperty(ERROR_KEY, this.errorMsg);
} else if (this.valueMsg != null) {
- payloadResp.addProperty(this.valueKey, this.valueMsg);
+ payloadResp.addProperty(VALUE_KEY, this.valueMsg);
} else if (this.infoMsg != null) {
- payloadResp.addProperty(this.infoKey, this.infoMsg);
+ payloadResp.addProperty(INFO_KEY, this.infoMsg);
}
return TransportProtos.ToDeviceRpcResponseMsg.newBuilder()
.setPayload(payloadResp.getAsJsonObject().toString())
@@ -110,13 +110,172 @@ public class Lwm2mClientRpcRequest {
.build();
}
- @Override
- public Object clone() {
+ private void init(DefaultLwM2MTransportMsgHandler handler) {
try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- log.error("", e);
+ // #1
+ if (this.bodyParams.contains(KEY_NAME_KEY)) {
+ String targetIdVerStr = this.getValueKeyFromBody(KEY_NAME_KEY);
+ if (targetIdVerStr != null) {
+ String targetIdVer = handler.getPresentPathIntoProfile(sessionInfo, targetIdVerStr);
+ if (targetIdVer != null) {
+ this.targetIdVer = targetIdVer;
+ this.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s",
+ targetIdVerStr, targetIdVer));
+ }
+ }
+ }
+ if (this.getTargetIdVer() == null && this.bodyParams.contains(TARGET_ID_VER_KEY)) {
+ this.setValidTargetIdVerKey();
+ }
+ if (this.bodyParams.contains(VALUE_KEY)) {
+ this.value = this.getValueKeyFromBody(VALUE_KEY);
+ }
+ try {
+ if (this.bodyParams.contains(PARAMS_KEY)) {
+ this.setValidParamsKey(handler);
+ }
+ } catch (Exception e) {
+ this.setErrorMsg(String.format("Params of request is bad Json format. %s", e.getMessage()));
+ }
+
+ if (this.getTargetIdVer() == null
+ && !(OBSERVE_READ_ALL == this.getTypeOper()
+ || DISCOVER_ALL == this.getTypeOper()
+ || OBSERVE_CANCEL == this.getTypeOper()
+ || FW_UPDATE == this.getTypeOper())) {
+ this.setErrorMsg(TARGET_ID_VER_KEY + " and " +
+ KEY_NAME_KEY + " is null or bad format");
+ }
+ /**
+ * EXECUTE && WRITE_REPLACE - only for Resource or ResourceInstance
+ */
+ else if (this.getTargetIdVer() != null
+ && (EXECUTE == this.getTypeOper()
+ || WRITE_REPLACE == this.getTypeOper())
+ && !(new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.getTargetIdVer()))).isResource()
+ || new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.getTargetIdVer()))).isResourceInstance())) {
+ this.setErrorMsg("Invalid parameter " + TARGET_ID_VER_KEY
+ + ". Only Resource or ResourceInstance can be this operation");
+ }
+ } catch (Exception e) {
+ this.setErrorMsg(String.format("Bad format request. %s", e.getMessage()));
+ }
+
+ }
+
+ private void setValidTargetIdVerKey() {
+ String targetIdVerStr = this.getValueKeyFromBody(TARGET_ID_VER_KEY);
+ // targetIdVer without ver - ok
+ try {
+ // targetIdVer with/without ver - ok
+ this.targetIdVer = validPathIdVer(targetIdVerStr, this.registration);
+ if (this.targetIdVer != null) {
+ this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer);
+ }
+ } catch (Exception e) {
+ if (this.targetIdVer == null) {
+ this.errorMsg = TARGET_ID_VER_KEY + " - " + targetIdVerStr + " is not valid.";
+ }
+ }
+ }
+
+ private void setValidParamsKey(DefaultLwM2MTransportMsgHandler handler) {
+ String paramsStr = this.getValueKeyFromBody(PARAMS_KEY);
+ if (paramsStr != null) {
+ String params2Json =
+ START_JSON_KEY
+ + "\""
+ + paramsStr
+ .replaceAll(SEPARATOR_KEY, "\"" + SEPARATOR_KEY + "\"")
+ .replaceAll(FINISH_VALUE_KEY, "\"" + FINISH_VALUE_KEY + "\"")
+ + "\""
+ + FINISH_JSON_KEY;
+ // jsonObject
+ Map params = new Gson().fromJson(params2Json, new TypeToken>() {
+ }.getType());
+ if (WRITE_UPDATE == this.getTypeOper()) {
+ if (this.targetIdVer != null) {
+ Map paramsResourceId = this.convertParamsToResourceId((ConcurrentHashMap) params, handler);
+ if (paramsResourceId.size() > 0) {
+ this.setParams(paramsResourceId);
+ }
+ }
+ } else if (WRITE_ATTRIBUTES == this.getTypeOper()) {
+ this.setParams(params);
+ }
+ }
+ }
+
+ private String getValueKeyFromBody(String key) {
+ String valueKey = null;
+ int startInd = -1;
+ int finishInd = -1;
+ try {
+ switch (key) {
+ case KEY_NAME_KEY:
+ case TARGET_ID_VER_KEY:
+ case VALUE_KEY:
+ startInd = this.bodyParams.indexOf(SEPARATOR_KEY, this.bodyParams.indexOf(key));
+ finishInd = this.bodyParams.indexOf(FINISH_VALUE_KEY, this.bodyParams.indexOf(key));
+ if (startInd >= 0 && finishInd < 0) {
+ finishInd = this.bodyParams.indexOf(FINISH_JSON_KEY, this.bodyParams.indexOf(key));
+ }
+ break;
+ case PARAMS_KEY:
+ startInd = this.bodyParams.indexOf(START_JSON_KEY, this.bodyParams.indexOf(key));
+ finishInd = this.bodyParams.indexOf(FINISH_JSON_KEY, this.bodyParams.indexOf(key));
+ }
+ if (startInd >= 0 && finishInd > 0) {
+ valueKey = this.bodyParams.substring(startInd + 1, finishInd);
+ }
+ } catch (Exception e) {
+ log.error("", new TimeoutException());
+ }
+ /**
+ * ReplaceAll "\""
+ */
+ if (StringUtils.trimToNull(valueKey) != null) {
+ char[] chars = valueKey.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == 92 || chars[i] == 34) chars[i] = 32;
+ }
+ return key.equals(PARAMS_KEY) ? String.valueOf(chars) : String.valueOf(chars).replaceAll(" ", "");
}
return null;
}
+
+ private ConcurrentHashMap convertParamsToResourceId(ConcurrentHashMap params,
+ DefaultLwM2MTransportMsgHandler serviceImpl) {
+ Map paramsIdVer = new ConcurrentHashMap<>();
+ LwM2mPath targetId = new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.targetIdVer)));
+ if (targetId.isObjectInstance()) {
+ params.forEach((k, v) -> {
+ try {
+ int id = Integer.parseInt(k);
+ paramsIdVer.put(String.valueOf(id), v);
+ } catch (NumberFormatException e) {
+ String targetIdVer = serviceImpl.getPresentPathIntoProfile(sessionInfo, k);
+ if (targetIdVer != null) {
+ LwM2mPath lwM2mPath = new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(targetIdVer)));
+ paramsIdVer.put(String.valueOf(lwM2mPath.getResourceId()), v);
+ }
+ /** WRITE_UPDATE*/
+ else {
+ String rezId = this.getRezIdByResourceNameAndObjectInstanceId(k, serviceImpl);
+ if (rezId != null) {
+ paramsIdVer.put(rezId, v);
+ }
+ }
+ }
+ });
+ }
+ return (ConcurrentHashMap) paramsIdVer;
+ }
+
+ private String getRezIdByResourceNameAndObjectInstanceId(String resourceName, DefaultLwM2MTransportMsgHandler handler) {
+ LwM2mClient lwM2mClient = handler.clientContext.getClient(this.sessionInfo);
+ return lwM2mClient != null ?
+ lwM2mClient.getRezIdByResourceNameAndObjectInstanceId(resourceName, this.targetIdVer, handler.config.getModelProvider()) :
+ null;
+ }
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java
index 1de2c1a4aa..365b92bf66 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java
@@ -214,9 +214,9 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto
// Add or update expiration
addOrUpdateExpiration(connection, updatedRegistration);
- // Update secondary index :
- // If registration is already associated to this address we don't care as we only want to keep the most
- // recent binding.
+ /** Update secondary index :
+ * If registration is already associated to this address we don't care as we only want to keep the most
+ * recent binding. */
byte[] addr_idx = toRegAddrKey(updatedRegistration.getSocketAddress());
connection.set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8));
if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) {
@@ -337,23 +337,24 @@ public class TbLwM2mRedisRegistrationStore implements CaliforniumRegistrationSto
}
}
+ //TODO: JedisCluster didn't implement Transaction, maybe should use some advanced key creation strategies
private void removeAddrIndex(RedisConnection connection, Registration registration) {
// Watch the key to remove.
byte[] regAddrKey = toRegAddrKey(registration.getSocketAddress());
- connection.watch(regAddrKey);
+// connection.watch(regAddrKey);
byte[] epFromAddr = connection.get(regAddrKey);
// Delete the key if needed.
if (Arrays.equals(epFromAddr, registration.getEndpoint().getBytes(UTF_8))) {
// Try to delete the key
- connection.multi();
+// connection.multi();
connection.del(regAddrKey);
- connection.exec();
+// connection.exec();
// if transaction failed this is not an issue as the socket address is probably reused and we don't neeed to
// delete it anymore.
} else {
// the key must not be deleted.
- connection.unwatch();
+// connection.unwatch();
}
}
diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java
index acc6ea1857..9a36b79051 100644
--- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java
+++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java
@@ -43,6 +43,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
@Override
public Object convertValue(Object value, Type currentType, Type expectedType, LwM2mPath resourcePath)
throws CodecException {
+ if (value == null) {
+ return null;
+ }
if (expectedType == null) {
/** unknown resource, trusted value */
return value;
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
index 7d50ea2f7d..961c20ed34 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
@@ -47,8 +47,8 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.TransportPayloadType;
import org.thingsboard.server.common.data.device.profile.MqttTopics;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
-import org.thingsboard.server.common.data.id.FirmwareId;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
+import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.msg.EncryptionUtil;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.common.transport.SessionMsgListener;
@@ -126,8 +126,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
private volatile InetSocketAddress address;
private volatile GatewaySessionHandler gatewaySessionHandler;
- private final ConcurrentHashMap fwSessions;
- private final ConcurrentHashMap fwChunkSizes;
+ private final ConcurrentHashMap otaPackSessions;
+ private final ConcurrentHashMap chunkSizes;
MqttTransportHandler(MqttTransportContext context, SslHandler sslHandler) {
this.sessionId = UUID.randomUUID();
@@ -137,8 +137,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
this.sslHandler = sslHandler;
this.mqttQoSMap = new ConcurrentHashMap<>();
this.deviceSessionCtx = new DeviceSessionCtx(sessionId, mqttQoSMap, context);
- this.fwSessions = new ConcurrentHashMap<>();
- this.fwChunkSizes = new ConcurrentHashMap<>();
+ this.otaPackSessions = new ConcurrentHashMap<>();
+ this.chunkSizes = new ConcurrentHashMap<>();
}
@Override
@@ -320,9 +320,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
TransportProtos.ClaimDeviceMsg claimDeviceMsg = payloadAdaptor.convertToClaimDevice(deviceSessionCtx, mqttMsg);
transportService.process(deviceSessionCtx.getSessionInfo(), claimDeviceMsg, getPubAckCallback(ctx, msgId, claimDeviceMsg));
} else if ((fwMatcher = FW_REQUEST_PATTERN.matcher(topicName)).find()) {
- getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.FIRMWARE);
+ getOtaPackageCallback(ctx, mqttMsg, msgId, fwMatcher, OtaPackageType.FIRMWARE);
} else if ((fwMatcher = SW_REQUEST_PATTERN.matcher(topicName)).find()) {
- getFirmwareCallback(ctx, mqttMsg, msgId, fwMatcher, FirmwareType.SOFTWARE);
+ getOtaPackageCallback(ctx, mqttMsg, msgId, fwMatcher, OtaPackageType.SOFTWARE);
} else {
transportService.reportActivity(deviceSessionCtx.getSessionInfo());
ack(ctx, msgId);
@@ -334,38 +334,38 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
}
- private void getFirmwareCallback(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, FirmwareType type) {
+ private void getOtaPackageCallback(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, OtaPackageType type) {
String payload = mqttMsg.content().toString(UTF8);
int chunkSize = StringUtils.isNotEmpty(payload) ? Integer.parseInt(payload) : 0;
String requestId = fwMatcher.group("requestId");
int chunk = Integer.parseInt(fwMatcher.group("chunk"));
if (chunkSize > 0) {
- this.fwChunkSizes.put(requestId, chunkSize);
+ this.chunkSizes.put(requestId, chunkSize);
} else {
- chunkSize = fwChunkSizes.getOrDefault(requestId, 0);
+ chunkSize = chunkSizes.getOrDefault(requestId, 0);
}
if (chunkSize > context.getMaxPayloadSize()) {
- sendFirmwareError(ctx, PAYLOAD_TOO_LARGE);
+ sendOtaPackageError(ctx, PAYLOAD_TOO_LARGE);
return;
}
- String firmwareId = fwSessions.get(requestId);
+ String otaPackageId = otaPackSessions.get(requestId);
- if (firmwareId != null) {
- sendFirmware(ctx, mqttMsg.variableHeader().packetId(), firmwareId, requestId, chunkSize, chunk, type);
+ if (otaPackageId != null) {
+ sendOtaPackage(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
} else {
TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo();
- TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder()
+ TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setType(type.name())
.build();
- transportService.process(deviceSessionCtx.getSessionInfo(), getFirmwareRequestMsg,
- new FirmwareCallback(ctx, msgId, getFirmwareRequestMsg, requestId, chunkSize, chunk));
+ transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
+ new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk));
}
}
@@ -425,15 +425,15 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
}
- private class FirmwareCallback implements TransportServiceCallback {
+ private class OtaPackageCallback implements TransportServiceCallback {
private final ChannelHandlerContext ctx;
private final int msgId;
- private final TransportProtos.GetFirmwareRequestMsg msg;
+ private final TransportProtos.GetOtaPackageRequestMsg msg;
private final String requestId;
private final int chunkSize;
private final int chunk;
- FirmwareCallback(ChannelHandlerContext ctx, int msgId, TransportProtos.GetFirmwareRequestMsg msg, String requestId, int chunkSize, int chunk) {
+ OtaPackageCallback(ChannelHandlerContext ctx, int msgId, TransportProtos.GetOtaPackageRequestMsg msg, String requestId, int chunkSize, int chunk) {
this.ctx = ctx;
this.msgId = msgId;
this.msg = msg;
@@ -443,13 +443,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
@Override
- public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) {
+ public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) {
if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) {
- FirmwareId firmwareId = new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB()));
- fwSessions.put(requestId, firmwareId.toString());
- sendFirmware(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk, FirmwareType.valueOf(response.getType()));
+ OtaPackageId firmwareId = new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()));
+ otaPackSessions.put(requestId, firmwareId.toString());
+ sendOtaPackage(ctx, msgId, firmwareId.toString(), requestId, chunkSize, chunk, OtaPackageType.valueOf(response.getType()));
} else {
- sendFirmwareError(ctx, response.getResponseStatus().toString());
+ sendOtaPackageError(ctx, response.getResponseStatus().toString());
}
}
@@ -460,11 +460,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
}
- private void sendFirmware(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, FirmwareType type) {
+ private void sendOtaPackage(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, OtaPackageType type) {
log.trace("[{}] Send firmware [{}] to device!", sessionId, firmwareId);
ack(ctx, msgId);
try {
- byte[] firmwareChunk = context.getFirmwareDataCache().get(firmwareId, chunkSize, chunk);
+ byte[] firmwareChunk = context.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk);
deviceSessionCtx.getPayloadAdaptor()
.convertToPublish(deviceSessionCtx, firmwareChunk, requestId, chunk, type)
.ifPresent(deviceSessionCtx.getChannel()::writeAndFlush);
@@ -473,7 +473,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
}
- private void sendFirmwareError(ChannelHandlerContext ctx, String error) {
+ private void sendOtaPackageError(ChannelHandlerContext ctx, String error) {
log.warn("[{}] {}", sessionId, error);
deviceSessionCtx.getChannel().writeAndFlush(deviceSessionCtx
.getPayloadAdaptor()
@@ -804,8 +804,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
@Override
- public void onRemoteSessionCloseCommand(TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
- log.trace("[{}] Received the remote command to close the session", sessionId);
+ public void onRemoteSessionCloseCommand(UUID sessionId, TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
+ log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
processDisconnect(deviceSessionCtx.getChannel());
}
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
index a9d7b3e2ea..19d2e15fc5 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
@@ -30,7 +30,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.device.profile.MqttTopics;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.gen.transport.TransportProtos;
@@ -155,7 +155,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
}
@Override
- public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) {
+ public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) {
return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
}
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java
index d0c1f30524..62ae6ae027 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java
@@ -23,7 +23,7 @@ import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import io.netty.handler.codec.mqtt.MqttPublishVariableHeader;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
@@ -78,7 +78,7 @@ public interface MqttTransportAdaptor {
Optional convertToPublish(MqttDeviceAwareSessionContext ctx, ProvisionDeviceResponseMsg provisionResponse) throws AdaptorException;
- Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException;
+ Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) throws AdaptorException;
default MqttPublishMessage createMqttPublishMsg(MqttDeviceAwareSessionContext ctx, String topic, byte[] payloadInBytes) {
MqttFixedHeader mqttFixedHeader =
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java
index 08a2f9abe3..a007c73a5a 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java
@@ -28,7 +28,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.device.profile.MqttTopics;
-import org.thingsboard.server.common.data.firmware.FirmwareType;
+import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.common.transport.adaptor.ProtoConverter;
@@ -168,7 +168,7 @@ public class ProtoMqttAdaptor implements MqttTransportAdaptor {
}
@Override
- public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, FirmwareType firmwareType) throws AdaptorException {
+ public Optional convertToPublish(MqttDeviceAwareSessionContext ctx, byte[] firmwareChunk, String requestId, int chunk, OtaPackageType firmwareType) throws AdaptorException {
return Optional.of(createMqttPublishMsg(ctx, String.format(DEVICE_SOFTWARE_FIRMWARE_RESPONSES_TOPIC_FORMAT, firmwareType.getKeyPrefix(), requestId, chunk), firmwareChunk));
}
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java
index e8d9a6b6d4..707586b7de 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java
@@ -96,7 +96,8 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple
}
@Override
- public void onRemoteSessionCloseCommand(TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
+ public void onRemoteSessionCloseCommand(UUID sessionId, TransportProtos.SessionCloseNotificationProto sessionCloseNotification) {
+ log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
parent.deregisterSession(getDeviceInfo().getDeviceName());
}
diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java
index a59ce020ba..ce70ece5ff 100644
--- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java
+++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java
@@ -132,7 +132,8 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S
}
@Override
- public void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification) {
+ public void onRemoteSessionCloseCommand(UUID sessionId, SessionCloseNotificationProto sessionCloseNotification) {
+ log.trace("[{}] Received the remote command to close the session: {}", sessionId, sessionCloseNotification.getMessage());
}
@Override
diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java
index 434441bdee..2eaf8dbf7c 100644
--- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java
+++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java
@@ -27,6 +27,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseM
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
import java.util.Optional;
+import java.util.UUID;
/**
* Created by ashvayka on 04.10.18.
@@ -37,7 +38,7 @@ public interface SessionMsgListener {
void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification);
- void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification);
+ void onRemoteSessionCloseCommand(UUID sessionId, SessionCloseNotificationProto sessionCloseNotification);
void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest);
diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java
index d4798108c6..d48d3fd04e 100644
--- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java
+++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java
@@ -21,14 +21,13 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.common.util.ThingsBoardExecutors;
-import org.thingsboard.server.cache.firmware.FirmwareDataCache;
+import org.thingsboard.server.cache.ota.OtaPackageDataCache;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.scheduler.SchedulerComponent;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
/**
* Created by ashvayka on 15.10.18.
@@ -53,7 +52,7 @@ public abstract class TransportContext {
@Getter
@Autowired
- private FirmwareDataCache firmwareDataCache;
+ private OtaPackageDataCache otaPackageDataCache;
@Autowired
private TransportResourceCache transportResourceCache;
diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java
index 2209ffc305..4a4e68f64f 100644
--- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java
+++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java
@@ -29,8 +29,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.GetFirmwareRequestMsg;
-import org.thingsboard.server.gen.transport.TransportProtos.GetFirmwareResponseMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg;
+import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg;
@@ -115,7 +115,7 @@ public interface TransportService {
void process(TransportToDeviceActorMsg msg, TransportServiceCallback callback);
- void process(SessionInfoProto sessionInfoProto, GetFirmwareRequestMsg msg, TransportServiceCallback callback);
+ void process(SessionInfoProto sessionInfoProto, GetOtaPackageRequestMsg msg, TransportServiceCallback