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 b755a31f4c..467a883129 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -38,14 +38,12 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.server.common.data.ClaimRequest; -import org.thingsboard.server.common.data.Customer; 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.EntitySubtype; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -66,7 +64,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.device.DeviceBulkImportService; -import org.thingsboard.server.service.entitiy.TbDeviceService; +import org.thingsboard.server.service.entitiy.device.TbDeviceService; import org.thingsboard.server.service.importing.BulkImportRequest; import org.thingsboard.server.service.importing.BulkImportResult; import org.thingsboard.server.service.security.model.SecurityUser; @@ -74,7 +72,6 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import javax.annotation.Nullable; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -206,7 +203,11 @@ public class DeviceController extends BaseController { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); checkDeviceId(deviceId, Operation.DELETE); - tbDeviceService.deleteDevice(getCurrentUser(), getTenantId(), deviceId); + try { + tbDeviceService.deleteDevice(getCurrentUser(), getTenantId(), deviceId).get(); + } catch (Exception e) { + throw handleException(e); + } } @ApiOperation(value = "Assign device to customer (assignDeviceToCustomer)", @@ -550,52 +551,42 @@ public class DeviceController extends BaseController { @ApiParam(value = "Claiming request which can optionally contain secret key") @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException { checkParameter(DEVICE_NAME, deviceName); - try { - final DeferredResult deferredResult = new DeferredResult<>(); + final DeferredResult deferredResult = new DeferredResult<>(); - SecurityUser user = getCurrentUser(); - TenantId tenantId = user.getTenantId(); - CustomerId customerId = user.getCustomerId(); + SecurityUser user = getCurrentUser(); + TenantId tenantId = user.getTenantId(); + CustomerId customerId = user.getCustomerId(); - Device device = checkNotNull(deviceService.findDeviceByTenantIdAndName(tenantId, deviceName)); - accessControlService.checkPermission(user, Resource.DEVICE, Operation.CLAIM_DEVICES, - device.getId(), device); - String secretKey = getSecretKey(claimRequest); + Device device = checkNotNull(deviceService.findDeviceByTenantIdAndName(tenantId, deviceName)); + accessControlService.checkPermission(user, Resource.DEVICE, Operation.CLAIM_DEVICES, + device.getId(), device); + String secretKey = getSecretKey(claimRequest); - ListenableFuture future = claimDevicesService.claimDevice(device, customerId, secretKey); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable ClaimResult result) { - HttpStatus status; - if (result != null) { - if (result.getResponse().equals(ClaimResponse.SUCCESS)) { - status = HttpStatus.OK; - deferredResult.setResult(new ResponseEntity<>(result, status)); + ListenableFuture future = tbDeviceService.claimDevice(tenantId, device, customerId, secretKey, user); - try { - logEntityAction(user, device.getId(), result.getDevice(), customerId, ActionType.ASSIGNED_TO_CUSTOMER, null, - device.getId().toString(), customerId.toString(), customerService.findCustomerById(tenantId, customerId).getName()); - } catch (ThingsboardException e) { - throw new RuntimeException(e); - } - } else { - status = HttpStatus.BAD_REQUEST; - deferredResult.setResult(new ResponseEntity<>(result.getResponse(), status)); - } + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(@Nullable ClaimResult result) { + HttpStatus status; + if (result != null) { + if (result.getResponse().equals(ClaimResponse.SUCCESS)) { + status = HttpStatus.OK; + deferredResult.setResult(new ResponseEntity<>(result, status)); } else { - deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); + status = HttpStatus.BAD_REQUEST; + deferredResult.setResult(new ResponseEntity<>(result.getResponse(), status)); } + } else { + deferredResult.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); } + } - @Override - public void onFailure(Throwable t) { - deferredResult.setErrorResult(t); - } - }, MoreExecutors.directExecutor()); - return deferredResult; - } catch (Exception e) { - throw handleException(e); - } + @Override + public void onFailure(Throwable t) { + deferredResult.setErrorResult(t); + } + }, MoreExecutors.directExecutor()); + return deferredResult; } @ApiOperation(value = "Reclaim device (reClaimDevice)", @@ -617,21 +608,11 @@ public class DeviceController extends BaseController { accessControlService.checkPermission(user, Resource.DEVICE, Operation.CLAIM_DEVICES, device.getId(), device); - ListenableFuture result = claimDevicesService.reClaimDevice(tenantId, device); + ListenableFuture result = tbDeviceService.reclaimDevice(tenantId, device, user); Futures.addCallback(result, new FutureCallback<>() { @Override public void onSuccess(ReclaimResult reclaimResult) { deferredResult.setResult(new ResponseEntity(HttpStatus.OK)); - - Customer unassignedCustomer = reclaimResult.getUnassignedCustomer(); - if (unassignedCustomer != null) { - try { - logEntityAction(user, device.getId(), device, device.getCustomerId(), ActionType.UNASSIGNED_FROM_CUSTOMER, null, - device.getId().toString(), unassignedCustomer.getId().toString(), unassignedCustomer.getName()); - } catch (ThingsboardException e) { - throw new RuntimeException(e); - } - } } @Override @@ -645,7 +626,7 @@ public class DeviceController extends BaseController { } } - private String getSecretKey(ClaimRequest claimRequest) throws IOException { + private String getSecretKey(ClaimRequest claimRequest) { String secretKey = claimRequest.getSecretKey(); if (secretKey != null) { return secretKey; @@ -667,7 +648,6 @@ public class DeviceController extends BaseController { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); checkDeviceId(deviceId, Operation.ASSIGN_TO_TENANT); - //TODO: use checkTenantId TenantId newTenantId = TenantId.fromUUID(toUUID(strTenantId)); Tenant newTenant = tenantService.findTenantById(newTenantId); if (newTenant == null) { @@ -813,7 +793,6 @@ public class DeviceController extends BaseController { Exception { SecurityUser user = getCurrentUser(); return deviceBulkImportService.processBulkImport(request, user, importedDeviceInfo -> { -// onDeviceCreatedOrUpdated(importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), importedDeviceInfo.isUpdated(), user); }); } diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java index 00d81719e2..7b8fdc325a 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceBulkImportService.java @@ -49,7 +49,7 @@ import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.service.entitiy.TbDeviceService; +import org.thingsboard.server.service.entitiy.device.TbDeviceService; import org.thingsboard.server.service.importing.AbstractBulkImportService; import org.thingsboard.server.service.importing.BulkImportColumnType; import org.thingsboard.server.service.security.model.SecurityUser; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java index 0499e281dc..97c6907740 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.entitiy; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -23,17 +22,13 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AlarmId; @@ -45,10 +40,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.common.msg.queue.TbCallback; -import org.thingsboard.server.dao.alarm.AlarmOperationResult; import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.device.ClaimDevicesService; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeService; @@ -82,6 +76,8 @@ public abstract class AbstractTbEntityService { @Autowired protected DbCallbackExecutorService dbExecutor; + @Autowired + protected TbNotificationEntityService notificationEntityService; @Autowired(required = false) protected EdgeService edgeService; @Autowired @@ -98,19 +94,20 @@ public abstract class AbstractTbEntityService { protected TenantService tenantService; @Autowired protected CustomerService customerService; + @Autowired + protected ClaimDevicesService claimDevicesService; - protected void removeAlarmsByEntityId(TenantId tenantId, EntityId entityId, TbCallback callback) { + protected ListenableFuture removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) { ListenableFuture> alarmsFuture = alarmService.findAlarms(tenantId, new AlarmQuery(entityId, new TimePageLink(Integer.MAX_VALUE), null, null, false)); ListenableFuture> alarmIdsFuture = Futures.transform(alarmsFuture, page -> page.getData().stream().map(AlarmInfo::getId).collect(Collectors.toList()), dbExecutor); - ListenableFuture> resultFuture = Futures.transform(alarmIdsFuture, ids -> - ids.stream().map(alarmId -> alarmService.deleteAlarm(tenantId, alarmId)).collect(Collectors.toList()), - dbExecutor); - - DonAsynchron.withCallback(resultFuture, result -> callback.onSuccess(), callback::onFailure, dbExecutor); + return Futures.transform(alarmIdsFuture, ids -> { + ids.stream().map(alarmId -> alarmService.deleteAlarm(tenantId, alarmId)).collect(Collectors.toList()); + return null; + }, dbExecutor); } protected void logEntityAction(User user, TenantId tenantId, I entityId, E entity, CustomerId customerId, @@ -171,46 +168,6 @@ public abstract class AbstractTbEntityService { } } - protected void sendEntityAssignToCustomerNotificationMsg(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { - try { - sendNotificationMsgToEdgeService(tenantId, null, entityId, json.writeValueAsString(customerId), null, action); - } catch (Exception e) { - log.warn("Failed to push assign/unassign to/from customer to core: {}", customerId, e); - } - } - - protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds) { - sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); - } - - protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds, String body) { - if (edgeIds != null && !edgeIds.isEmpty()) { - for (EdgeId edgeId : edgeIds) { - sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, null, EdgeEventActionType.DELETED); - } - } - } - - protected void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action) { - sendNotificationMsgToEdgeService(tenantId, null, entityId, null, null, action); - } - - protected void sendEntityAssignToEdgeNotificationMsg(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) { - sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, null, action); - } - - private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { - tbClusterService.sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, type, action); - } - - protected void sendAlarmDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds, Alarm alarm) { - try { - sendDeleteNotificationMsg(tenantId, entityId, edgeIds, json.writeValueAsString(alarm)); - } catch (Exception e) { - log.warn("Failed to push delete alarm msg to core: {}", alarm, e); - } - } - @SuppressWarnings("unchecked") protected I emptyId(EntityType entityType) { return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); @@ -231,13 +188,4 @@ public abstract class AbstractTbEntityService { } return result; } - - protected String entityToStr(E entity) { - try { - return json.writeValueAsString(json.valueToTree(entity)); - } catch (JsonProcessingException e) { - log.warn("[{}] Failed to convert entity to string!", entity, e); - } - return null; - } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbDeviceService.java deleted file mode 100644 index 3e64462d2f..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbDeviceService.java +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Copyright © 2016-2022 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.entitiy; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; -import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; -import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.security.DeviceCredentials; -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.gateway_device.GatewayNotificationsService; -import org.thingsboard.server.service.security.model.SecurityUser; - -import java.util.List; - -@AllArgsConstructor -@TbCoreComponent -@Service -@Slf4j -public class DefaultTbDeviceService extends AbstractTbEntityService implements TbDeviceService { - - private final GatewayNotificationsService gatewayNotificationsService; - - @Override - public Device save(SecurityUser user, TenantId tenantId, Device device, Device oldDevice, String accessToken) throws ThingsboardException { - boolean created = device.getId() == null; - try { - Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); - tbClusterService.onDeviceUpdated(savedDevice, oldDevice); - - logEntityAction(user, tenantId, savedDevice.getId(), savedDevice, - savedDevice.getCustomerId(), - created ? ActionType.ADDED : ActionType.UPDATED, null); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), device, - null, created ? ActionType.ADDED : ActionType.UPDATED, e); - throw handleException(e); - } - } - - @Override - public Device saveDeviceWithCredentials(SecurityUser user, TenantId tenantId, Device device, DeviceCredentials credentials) throws ThingsboardException { - boolean created = device.getId() == null; - try { - Device savedDevice = checkNotNull(deviceService.saveDeviceWithCredentials(device, credentials)); - tbClusterService.onDeviceUpdated(savedDevice, device); - logEntityAction(user, tenantId, savedDevice.getId(), savedDevice, - savedDevice.getCustomerId(), - created ? ActionType.ADDED : ActionType.UPDATED, null); - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), device, - null, created ? ActionType.ADDED : ActionType.UPDATED, e); - throw handleException(e); - } - } - - @Override - public void deleteDevice(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { - try { - Device device = deviceService.findDeviceById(tenantId, deviceId); - List relatedEdgeIds = findRelatedEdgeIds(tenantId, deviceId); - - deviceService.deleteDevice(tenantId, deviceId); - - gatewayNotificationsService.onDeviceDeleted(device); - tbClusterService.onDeviceDeleted(device, null); - - logEntityAction(user, tenantId, deviceId, device, - device.getCustomerId(), - ActionType.DELETED, null, deviceId.toString()); - - sendDeleteNotificationMsg(tenantId, deviceId, relatedEdgeIds); - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), - null, - null, - ActionType.DELETED, e, deviceId.toString()); - throw handleException(e); - } - } - - @Override - public Device assignDeviceToCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId, CustomerId customerId) throws ThingsboardException { - try { - Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(user.getTenantId(), deviceId, customerId)); - - Customer customer = customerService.findCustomerById(user.getTenantId(), customerId); - - logEntityAction(user, tenantId, deviceId, savedDevice, - savedDevice.getCustomerId(), - ActionType.ASSIGNED_TO_CUSTOMER, null, deviceId.toString(), customerId.toString(), customer.getName()); - - sendEntityAssignToCustomerNotificationMsg(savedDevice.getTenantId(), savedDevice.getId(), - customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, deviceId.toString(), customerId.toString()); - throw handleException(e); - } - } - - @Override - public Device unassignDeviceFromCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { - try { - Device device = deviceService.findDeviceById(tenantId, deviceId); - Customer customer = customerService.findCustomerById(tenantId, device.getCustomerId()); - Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(tenantId, deviceId)); - - logEntityAction(user, tenantId, deviceId, device, - device.getCustomerId(), - ActionType.UNASSIGNED_FROM_CUSTOMER, null, deviceId.toString(), customer.getId().toString(), customer.getName()); - - sendEntityAssignToCustomerNotificationMsg(savedDevice.getTenantId(), savedDevice.getId(), - customer.getId(), EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.UNASSIGNED_FROM_CUSTOMER, e, deviceId.toString()); - throw handleException(e); - } - } - - @Override - public Device assignDeviceToPublicCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { - try { - Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); - Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, publicCustomer.getId())); - - logEntityAction(user, tenantId, deviceId, savedDevice, - savedDevice.getCustomerId(), - ActionType.ASSIGNED_TO_CUSTOMER, null, deviceId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, deviceId.toString()); - throw handleException(e); - } - } - - @Override - public DeviceCredentials getDeviceCredentialsByDeviceId(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { - try { - Device device = deviceService.findDeviceById(tenantId, deviceId); - DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId)); - logEntityAction(user, tenantId, deviceId, device, - device.getCustomerId(), - ActionType.CREDENTIALS_READ, null, deviceId.toString()); - return deviceCredentials; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.CREDENTIALS_READ, e, deviceId.toString()); - throw handleException(e); - } - } - - @Override - public DeviceCredentials updateDeviceCredentials(SecurityUser user, TenantId tenantId, DeviceCredentials deviceCredentials) throws ThingsboardException { - try { - DeviceId deviceId = deviceCredentials.getDeviceId(); - Device device = deviceService.findDeviceById(tenantId, deviceId); - DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials)); - tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), result), null); - - sendEntityNotificationMsg(tenantId, device.getId(), EdgeEventActionType.CREDENTIALS_UPDATED); - - logEntityAction(user, tenantId, deviceId, device, - device.getCustomerId(), - ActionType.CREDENTIALS_UPDATED, null, deviceCredentials); - return result; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.CREDENTIALS_UPDATED, e, deviceCredentials); - throw handleException(e); - } - } - - @Override - public Device assignDeviceToTenant(SecurityUser user, TenantId tenantId, TenantId newTenantId, DeviceId deviceId) throws ThingsboardException { - try { - Tenant newTenant = tenantService.findTenantById(newTenantId); - Device device = deviceService.findDeviceById(tenantId, deviceId); - - Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device); - - logEntityAction(user, tenantId, deviceId, assignedDevice, - assignedDevice.getCustomerId(), - ActionType.ASSIGNED_TO_TENANT, null, newTenantId.toString(), newTenant.getName()); - - Tenant currentTenant = tenantService.findTenantById(tenantId); - pushAssignedFromNotification(currentTenant, newTenantId, assignedDevice); - - return assignedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.ASSIGNED_TO_TENANT, e, newTenantId.toString()); - throw handleException(e); - } - } - - @Override - public Device assignDeviceToEdge(SecurityUser user, TenantId tenantId, DeviceId deviceId, EdgeId edgeId) throws ThingsboardException { - try { - Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId)); - Edge edge = edgeService.findEdgeById(tenantId, edgeId); - - logEntityAction(user, tenantId, deviceId, savedDevice, - savedDevice.getCustomerId(), - ActionType.ASSIGNED_TO_EDGE, null, deviceId.toString(), edgeId.toString(), edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, savedDevice.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.ASSIGNED_TO_EDGE, e, deviceId.toString(), edgeId.toString()); - throw handleException(e); - } - } - - @Override - public Device unassignDeviceFromEdge(SecurityUser user, TenantId tenantId, DeviceId deviceId, EdgeId edgeId) throws ThingsboardException { - try { - Device device = deviceService.findDeviceById(tenantId, deviceId); - Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId)); - Edge edge = edgeService.findEdgeById(tenantId, edgeId); - - logEntityAction(user, tenantId, deviceId, device, - device.getCustomerId(), - ActionType.UNASSIGNED_FROM_EDGE, null, deviceId.toString(), edgeId.toString(), edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, savedDevice.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); - - return savedDevice; - } catch (Exception e) { - logEntityAction(user, tenantId, emptyId(EntityType.DEVICE), null, - null, - ActionType.UNASSIGNED_FROM_EDGE, e, deviceId.toString(), edgeId.toString()); - throw handleException(e); - } - } - - private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) { - String data = entityToStr(assignedDevice); - if (data != null) { - TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(), assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data); - tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null); - } - } - - private TbMsgMetaData getMetaDataForAssignedFrom(Tenant tenant) { - TbMsgMetaData metaData = new TbMsgMetaData(); - metaData.putValue("assignedFromTenantId", tenant.getId().getId().toString()); - metaData.putValue("assignedFromTenantName", tenant.getName()); - return metaData; - } -} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java new file mode 100644 index 0000000000..ae508f5e3a --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -0,0 +1,220 @@ +/** + * Copyright © 2016-2022 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.entitiy; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; +import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; +import org.thingsboard.server.common.data.security.DeviceCredentials; +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.edge.EdgeService; +import org.thingsboard.server.service.action.EntityActionService; +import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; +import org.thingsboard.server.service.security.model.SecurityUser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DefaultTbNotificationEntityService implements TbNotificationEntityService { + + protected static final int DEFAULT_PAGE_SIZE = 1000; + + private static final ObjectMapper json = new ObjectMapper(); + + @Value("${edges.enabled}") + @Getter + protected boolean edgesEnabled; + + private final EntityActionService entityActionService; + private final TbClusterService tbClusterService; + private final GatewayNotificationsService gatewayNotificationsService; + private final EdgeService edgeService; + + @Override + public void sendNotification(TenantId tenantId, I entityId, E entity, CustomerId customerId, + ActionType actionType, SecurityUser user, Exception e, + Object... additionalInfo) { + logEntityAction(tenantId, entityId, entity, customerId, actionType, user, e, additionalInfo); + } + + //Device + @Override + public void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, + Device device, Device oldDevice, ActionType actionType, + SecurityUser user, Object... additionalInfo) { + tbClusterService.onDeviceUpdated(device, oldDevice); + logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo); + } + + @Override + public void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, + SecurityUser user, Object... additionalInfo) { + gatewayNotificationsService.onDeviceDeleted(device); + tbClusterService.onDeviceDeleted(device, null); + + logEntityAction(tenantId, deviceId, device, customerId, ActionType.DELETED, user, additionalInfo); + + List relatedEdgeIds = findRelatedEdgeIds(tenantId, deviceId); + sendDeleteNotificationMsg(tenantId, deviceId, relatedEdgeIds); + } + + @Override + public void notifyAssignOrUnassignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId, + Device device, ActionType actionType, EdgeEventActionType edgeActionType, + SecurityUser user, boolean sendToEdge, Object... additionalInfo) { + logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo); + + if (sendToEdge) { + sendEntityAssignToCustomerNotificationMsg(tenantId, deviceId, customerId, edgeActionType); + } + } + + @Override + public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, + DeviceCredentials deviceCredentials, SecurityUser user) { + tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null); + sendEntityNotificationMsg(tenantId, deviceId, EdgeEventActionType.CREDENTIALS_UPDATED); + logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials); + } + + @Override + public void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, + Device device, Tenant tenant, SecurityUser user, Object... additionalInfo) { + logEntityAction(tenantId, deviceId, device, customerId, ActionType.ASSIGNED_TO_TENANT, user, additionalInfo); + pushAssignedFromNotification(tenant, newTenantId, device); + } + + @Override + public void notifyAssignOrUnassignDeviceToEdge(TenantId tenantId, DeviceId deviceId, CustomerId customerId, EdgeId edgeId, + Device device, ActionType actionType, EdgeEventActionType edgeActionType, + SecurityUser user, Object... additionalInfo) { + logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo); + sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, deviceId, edgeActionType); + } + + private void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId, + ActionType actionType, SecurityUser user, Object... additionalInfo) { + logEntityAction(tenantId, entityId, entity, customerId, actionType, user, null, additionalInfo); + } + + private void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId, + ActionType actionType, SecurityUser user, Exception e, Object... additionalInfo) { + if (user != null) { + entityActionService.logEntityAction(user, entityId, entity, customerId, actionType, e, additionalInfo); + } else if (e == null) { + entityActionService.pushEntityActionToRuleEngine(entityId, entity, tenantId, customerId, actionType, null, additionalInfo); + } + } + + protected void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action) { + sendNotificationMsgToEdgeService(tenantId, null, entityId, null, null, action); + } + + protected void sendEntityAssignToCustomerNotificationMsg(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { + try { + sendNotificationMsgToEdgeService(tenantId, null, entityId, json.writeValueAsString(customerId), null, action); + } catch (Exception e) { + log.warn("Failed to push assign/unassign to/from customer to core: {}", customerId, e); + } + } + + protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds) { + sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); + } + + protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds, String body) { + if (edgeIds != null && !edgeIds.isEmpty()) { + for (EdgeId edgeId : edgeIds) { + sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, null, EdgeEventActionType.DELETED); + } + } + } + + protected void sendEntityAssignToEdgeNotificationMsg(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) { + sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, null, action); + } + + private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { + tbClusterService.sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, type, action); + } + + private List findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { + if (!edgesEnabled) { + return null; + } + if (EntityType.EDGE.equals(entityId.getEntityType())) { + return Collections.singletonList(new EdgeId(entityId.getId())); + } + PageDataIterableByTenantIdEntityId relatedEdgeIdsIterator = + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + List result = new ArrayList<>(); + for (EdgeId edgeId : relatedEdgeIdsIterator) { + result.add(edgeId); + } + return result; + } + + private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) { + String data = entityToStr(assignedDevice); + if (data != null) { + TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(), assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data); + tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null); + } + } + + private TbMsgMetaData getMetaDataForAssignedFrom(Tenant tenant) { + TbMsgMetaData metaData = new TbMsgMetaData(); + metaData.putValue("assignedFromTenantId", tenant.getId().getId().toString()); + metaData.putValue("assignedFromTenantName", tenant.getName()); + return metaData; + } + + private String entityToStr(E entity) { + try { + return json.writeValueAsString(json.valueToTree(entity)); + } catch (JsonProcessingException e) { + log.warn("[{}] Failed to convert entity to string!", entity, e); + } + return null; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java new file mode 100644 index 0000000000..4cd56f47fb --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -0,0 +1,56 @@ +/** + * Copyright © 2016-2022 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.entitiy; + +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.service.security.model.SecurityUser; + +public interface TbNotificationEntityService { + + void sendNotification(TenantId tenantId, I entityId, E entity, CustomerId customerId, + ActionType actionType, SecurityUser user, Exception e, + Object... additionalInfo); + + void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, + Device oldDevice, ActionType actionType, SecurityUser user, Object... additionalInfo); + + void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, + SecurityUser user, Object... additionalInfo); + + void notifyAssignOrUnassignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId, + Device device, ActionType actionType, EdgeEventActionType edgeActionType, + SecurityUser user, boolean sendToEdge, Object... additionalInfo); + + void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, + DeviceCredentials deviceCredentials, SecurityUser user); + + void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, + Device device, Tenant tenant, SecurityUser user, Object... additionalInfo); + + void notifyAssignOrUnassignDeviceToEdge(TenantId tenantId, DeviceId deviceId, CustomerId customerId, EdgeId edgeId, + Device device, ActionType actionType, EdgeEventActionType edgeActionType, + SecurityUser user, Object... additionalInfo); +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java new file mode 100644 index 0000000000..6e13b89358 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java @@ -0,0 +1,273 @@ +/** + * Copyright © 2016-2022 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.entitiy.device; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.dao.device.claim.ClaimResponse; +import org.thingsboard.server.dao.device.claim.ClaimResult; +import org.thingsboard.server.dao.device.claim.ReclaimResult; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; + +@AllArgsConstructor +@TbCoreComponent +@Service +@Slf4j +public class DefaultTbDeviceService extends AbstractTbEntityService implements TbDeviceService { + + @Override + public Device save(SecurityUser user, TenantId tenantId, Device device, Device oldDevice, String accessToken) throws ThingsboardException { + ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + try { + Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); + notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), + savedDevice, oldDevice, actionType, user); + + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), device, null, actionType, user, e); + throw handleException(e); + } + } + + @Override + public Device saveDeviceWithCredentials(SecurityUser user, TenantId tenantId, Device device, DeviceCredentials credentials) throws ThingsboardException { + ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + try { + Device savedDevice = checkNotNull(deviceService.saveDeviceWithCredentials(device, credentials)); + notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), + savedDevice, device, actionType, user); + + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), device, null, actionType, user, e); + throw handleException(e); + } + } + + @Override + public ListenableFuture deleteDevice(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { + try { + Device device = deviceService.findDeviceById(tenantId, deviceId); + deviceService.deleteDevice(tenantId, deviceId); + notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device, user, deviceId.toString()); + return removeAlarmsByEntityId(tenantId, deviceId); + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + ActionType.DELETED, user, e, deviceId.toString()); + throw handleException(e); + } + } + + @Override + public Device assignDeviceToCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId, CustomerId customerId) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + try { + Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(user.getTenantId(), deviceId, customerId)); + + Customer customer = customerService.findCustomerById(user.getTenantId(), customerId); + + notificationEntityService.notifyAssignOrUnassignDeviceToCustomer(tenantId, deviceId, customerId, savedDevice, + actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerId.toString(), customer.getName()); + + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, deviceId.toString(), customerId.toString()); + throw handleException(e); + } + } + + @Override + public Device unassignDeviceFromCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; + try { + Device device = deviceService.findDeviceById(tenantId, deviceId); + Customer customer = customerService.findCustomerById(tenantId, device.getCustomerId()); + Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(tenantId, deviceId)); + CustomerId customerId = customer.getId(); + + notificationEntityService.notifyAssignOrUnassignDeviceToCustomer(tenantId, deviceId, customerId, savedDevice, + actionType, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, + true, customerId.toString(), customer.getName()); + + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, false, deviceId.toString()); + throw handleException(e); + } + } + + @Override + public Device assignDeviceToPublicCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + try { + Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); + Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, publicCustomer.getId())); + + notificationEntityService.notifyAssignOrUnassignDeviceToCustomer(tenantId, deviceId, savedDevice.getCustomerId(), savedDevice, + actionType, null, user, false, deviceId.toString(), + publicCustomer.getId().toString(), publicCustomer.getName()); + + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, false, deviceId.toString()); + throw handleException(e); + } + } + + @Override + public DeviceCredentials getDeviceCredentialsByDeviceId(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException { + ActionType actionType = ActionType.CREDENTIALS_READ; + try { + Device device = deviceService.findDeviceById(tenantId, deviceId); + DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId)); + notificationEntityService.sendNotification(tenantId, deviceId, device, device.getCustomerId(), + actionType, user, null, deviceId.toString()); + return deviceCredentials; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, deviceId.toString()); + throw handleException(e); + } + } + + @Override + public DeviceCredentials updateDeviceCredentials(SecurityUser user, TenantId tenantId, DeviceCredentials deviceCredentials) throws ThingsboardException { + try { + DeviceId deviceId = deviceCredentials.getDeviceId(); + Device device = deviceService.findDeviceById(tenantId, deviceId); + DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials)); + notificationEntityService.notifyUpdateDeviceCredentials(tenantId, deviceId, device.getCustomerId(), device, result, user); + return result; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + ActionType.CREDENTIALS_UPDATED, user, e, deviceCredentials); + throw handleException(e); + } + } + + @Override + public ListenableFuture claimDevice(TenantId tenantId, Device device, CustomerId customerId, String secretKey, SecurityUser user) throws ThingsboardException { + try { + ListenableFuture future = claimDevicesService.claimDevice(device, customerId, secretKey); + + return Futures.transform(future, result -> { + if (result != null && result.getResponse().equals(ClaimResponse.SUCCESS)) { + notificationEntityService.sendNotification(tenantId, device.getId(), result.getDevice(), customerId, + ActionType.ASSIGNED_TO_CUSTOMER, user, null, device.getId().toString(), customerId.toString(), + customerService.findCustomerById(tenantId, customerId).getName()); + } + return result; + }, MoreExecutors.directExecutor()); + } catch (Exception e) { + throw handleException(e); + } + } + + @Override + public ListenableFuture reclaimDevice(TenantId tenantId, Device device, SecurityUser user) throws ThingsboardException { + try { + ListenableFuture future = claimDevicesService.reClaimDevice(tenantId, device); + + return Futures.transform(future, result -> { + Customer unassignedCustomer = result.getUnassignedCustomer(); + if (unassignedCustomer != null) { + notificationEntityService.sendNotification(tenantId, device.getId(), device, device.getCustomerId(), ActionType.UNASSIGNED_FROM_CUSTOMER, user, null, + device.getId().toString(), unassignedCustomer.getId().toString(), unassignedCustomer.getName()); + } + return result; + }, MoreExecutors.directExecutor()); + } catch (Exception e) { + throw handleException(e); + } + } + + @Override + public Device assignDeviceToTenant(SecurityUser user, TenantId tenantId, TenantId newTenantId, DeviceId deviceId) throws ThingsboardException { + try { + Tenant tenant = tenantService.findTenantById(tenantId); + Tenant newTenant = tenantService.findTenantById(newTenantId); + Device device = deviceService.findDeviceById(tenantId, deviceId); + Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device); + + notificationEntityService.notifyAssignDeviceToTenant(tenantId, newTenantId, deviceId, + assignedDevice.getCustomerId(), assignedDevice, tenant, user, newTenantId.toString(), newTenant.getName()); + + return assignedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + ActionType.ASSIGNED_TO_TENANT, user, e, newTenantId.toString()); + throw handleException(e); + } + } + + @Override + public Device assignDeviceToEdge(SecurityUser user, TenantId tenantId, DeviceId deviceId, EdgeId edgeId) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_EDGE; + try { + Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId)); + Edge edge = edgeService.findEdgeById(tenantId, edgeId); + notificationEntityService.notifyAssignOrUnassignDeviceToEdge(tenantId, deviceId, savedDevice.getCustomerId(), + edgeId, savedDevice, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, deviceId.toString(), edgeId.toString()); + throw handleException(e); + } + } + + @Override + public Device unassignDeviceFromEdge(SecurityUser user, TenantId tenantId, DeviceId deviceId, EdgeId edgeId) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE; + try { + Device device = deviceService.findDeviceById(tenantId, deviceId); + Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId)); + Edge edge = edgeService.findEdgeById(tenantId, edgeId); + + notificationEntityService.notifyAssignOrUnassignDeviceToEdge(tenantId, deviceId, device.getCustomerId(), + edgeId, device, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); + return savedDevice; + } catch (Exception e) { + notificationEntityService.sendNotification(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, deviceId.toString(), edgeId.toString()); + throw handleException(e); + } + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java similarity index 79% rename from application/src/main/java/org/thingsboard/server/service/entitiy/TbDeviceService.java rename to application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java index d4466d28a0..52fbf1da8a 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbDeviceService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.entitiy; +package org.thingsboard.server.service.entitiy.device; +import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; @@ -22,6 +23,8 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.dao.device.claim.ClaimResult; +import org.thingsboard.server.dao.device.claim.ReclaimResult; import org.thingsboard.server.service.security.model.SecurityUser; public interface TbDeviceService { @@ -30,7 +33,7 @@ public interface TbDeviceService { Device saveDeviceWithCredentials(SecurityUser user, TenantId tenantId, Device device, DeviceCredentials deviceCredentials) throws ThingsboardException; - void deleteDevice(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException; + ListenableFuture deleteDevice(SecurityUser user, TenantId tenantId, DeviceId deviceId) throws ThingsboardException; Device assignDeviceToCustomer(SecurityUser user, TenantId tenantId, DeviceId deviceId, CustomerId customerId) throws ThingsboardException; @@ -42,6 +45,10 @@ public interface TbDeviceService { DeviceCredentials updateDeviceCredentials(SecurityUser user, TenantId tenantId, DeviceCredentials deviceCredentials) throws ThingsboardException; + ListenableFuture claimDevice(TenantId tenantId, Device device, CustomerId customerId, String secretKey, SecurityUser user) throws ThingsboardException; + + ListenableFuture reclaimDevice(TenantId tenantId, Device device, SecurityUser user) throws ThingsboardException; + Device assignDeviceToTenant(SecurityUser user, TenantId tenantId, TenantId newTenantId, DeviceId deviceId) throws ThingsboardException; Device assignDeviceToEdge(SecurityUser user, TenantId tenantId, DeviceId deviceId, EdgeId edgeId) throws ThingsboardException;