8 changed files with 608 additions and 424 deletions
@ -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<EdgeId> 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; |
|||
} |
|||
} |
|||
@ -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 <E extends HasName, I extends EntityId> 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<EdgeId> 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 <E extends HasName, I extends EntityId> 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 <E extends HasName, I extends EntityId> 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<EdgeId> edgeIds) { |
|||
sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); |
|||
} |
|||
|
|||
protected void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> 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<EdgeId> findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { |
|||
if (!edgesEnabled) { |
|||
return null; |
|||
} |
|||
if (EntityType.EDGE.equals(entityId.getEntityType())) { |
|||
return Collections.singletonList(new EdgeId(entityId.getId())); |
|||
} |
|||
PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator = |
|||
new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); |
|||
List<EdgeId> 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 <E extends HasName> 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; |
|||
} |
|||
|
|||
} |
|||
@ -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 { |
|||
|
|||
<E extends HasName, I extends EntityId> 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); |
|||
} |
|||
@ -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<Void> 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<ClaimResult> claimDevice(TenantId tenantId, Device device, CustomerId customerId, String secretKey, SecurityUser user) throws ThingsboardException { |
|||
try { |
|||
ListenableFuture<ClaimResult> 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<ReclaimResult> reclaimDevice(TenantId tenantId, Device device, SecurityUser user) throws ThingsboardException { |
|||
try { |
|||
ListenableFuture<ReclaimResult> 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); |
|||
} |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue