Updated unassign for alarms, on user removing to be transactional
This commit is contained in:
		
							parent
							
								
									25778ce451
								
							
						
					
					
						commit
						ed5b528964
					
				@ -157,24 +157,6 @@ public class CustomerController extends BaseController {
 | 
			
		||||
        checkParameter(CUSTOMER_ID, strCustomerId);
 | 
			
		||||
        CustomerId customerId = new CustomerId(toUUID(strCustomerId));
 | 
			
		||||
        Customer customer = checkCustomerId(customerId, Operation.DELETE);
 | 
			
		||||
        TenantId tenantId = getTenantId();
 | 
			
		||||
        PageLink pl = new PageLink(100);
 | 
			
		||||
        boolean hasNext = true;
 | 
			
		||||
        List<ListenableFuture<Void>> futures = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        while (hasNext) {
 | 
			
		||||
            PageData<User> customerUsers = userService.findCustomerUsers(tenantId, customerId, pl);
 | 
			
		||||
            for (User user : customerUsers.getData()) {
 | 
			
		||||
                ListenableFuture<Void> future = tbAlarmService.unassignUserAlarms(tenantId, user, System.currentTimeMillis());
 | 
			
		||||
                futures.add(future);
 | 
			
		||||
            }
 | 
			
		||||
            hasNext = customerUsers.hasNext();
 | 
			
		||||
            if (hasNext) {
 | 
			
		||||
                pl = pl.nextPageLink();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ListenableFuture<List<Void>> allFutures = Futures.allAsList(futures);
 | 
			
		||||
        Futures.getChecked(allFutures, ThingsboardException.class);
 | 
			
		||||
        tbCustomerService.delete(customer, getCurrentUser());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.entitiy.alarm;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import com.google.common.util.concurrent.Futures;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
@ -32,7 +29,6 @@ import org.thingsboard.server.common.data.alarm.AlarmComment;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmCommentType;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmQueryV2;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmUpdateRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.audit.ActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
 | 
			
		||||
@ -40,8 +36,6 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EdgeId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -216,47 +210,6 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
 | 
			
		||||
        return alarmInfo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListenableFuture<Void> unassignUserAlarms(TenantId tenantId, User user, long unassignTs) {
 | 
			
		||||
        AlarmQueryV2 alarmQuery = AlarmQueryV2.builder().assigneeId(user.getId()).pageLink(new TimePageLink(Integer.MAX_VALUE)).build();
 | 
			
		||||
        ListenableFuture<PageData<AlarmInfo>> foundUserAlarmsFuture = alarmService.findAlarmsV2(tenantId, alarmQuery);
 | 
			
		||||
        FutureCallback<PageData<AlarmInfo>> callback = new FutureCallback<>() {
 | 
			
		||||
            public void onSuccess(PageData<AlarmInfo> alarmsData) {
 | 
			
		||||
                for (AlarmInfo alarm : alarmsData.getData()) {
 | 
			
		||||
                    unassignUserAlarm(tenantId, user, unassignTs, alarm);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public void onFailure(Throwable t) {
 | 
			
		||||
                log.error("Cannot get alarms for user {}", user.getId(), t);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        Futures.addCallback(foundUserAlarmsFuture, callback, dbExecutor);
 | 
			
		||||
        return Futures.transform(foundUserAlarmsFuture, alarms -> null, dbExecutor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void unassignUserAlarm(TenantId tenantId, User user, long unassignTs, AlarmInfo alarm) {
 | 
			
		||||
        AlarmApiCallResult result = alarmSubscriptionService.unassignAlarm(tenantId, alarm.getId(), getOrDefault(unassignTs));
 | 
			
		||||
        if (!result.isSuccessful()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (result.isModified()) {
 | 
			
		||||
            AlarmComment alarmComment = AlarmComment.builder()
 | 
			
		||||
                    .alarmId(alarm.getId())
 | 
			
		||||
                    .type(AlarmCommentType.SYSTEM)
 | 
			
		||||
                    .comment(JacksonUtil.newObjectNode().put("text", String.format("Alarm was unassigned because user %s - was deleted",
 | 
			
		||||
                                    (user.getFirstName() == null || user.getLastName() == null) ? user.getName() : user.getFirstName() + " " + user.getLastName()))
 | 
			
		||||
                            .put("userId", user.getId().toString())
 | 
			
		||||
                            .put("subtype", "ASSIGN"))
 | 
			
		||||
                    .build();
 | 
			
		||||
            try {
 | 
			
		||||
                alarmCommentService.saveAlarmComment(alarm, alarmComment, user);
 | 
			
		||||
            } catch (ThingsboardException e) {
 | 
			
		||||
                log.error("Failed to save alarm comment", e);
 | 
			
		||||
            }
 | 
			
		||||
            notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), ActionType.ALARM_UNASSIGNED, user);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean delete(Alarm alarm, User user) {
 | 
			
		||||
 | 
			
		||||
@ -15,12 +15,10 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.entitiy.alarm;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
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.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
 | 
			
		||||
public interface TbAlarmService {
 | 
			
		||||
@ -39,7 +37,5 @@ public interface TbAlarmService {
 | 
			
		||||
 | 
			
		||||
    AlarmInfo unassign(Alarm alarm, long unassignTs, User user) throws ThingsboardException;
 | 
			
		||||
 | 
			
		||||
    ListenableFuture<Void> unassignUserAlarms(TenantId tenantId, User user, long unassignTs);
 | 
			
		||||
 | 
			
		||||
    Boolean delete(Alarm alarm, User user);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.entitiy.user;
 | 
			
		||||
 | 
			
		||||
import com.google.common.util.concurrent.Futures;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
@ -84,8 +82,6 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
 | 
			
		||||
        UserId userId = tbUser.getId();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            ListenableFuture<Void> future = tbAlarmService.unassignUserAlarms(tbUser.getTenantId(), tbUser, System.currentTimeMillis());
 | 
			
		||||
            Futures.getChecked(future, ThingsboardException.class);
 | 
			
		||||
            userService.deleteUser(tenantId, userId);
 | 
			
		||||
            notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, userId, tbUser,
 | 
			
		||||
                    user, ActionType.DELETED, true, null, customerId.toString());
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ package org.thingsboard.server.dao.alarm;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import org.thingsboard.server.common.data.User;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.Alarm;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
 | 
			
		||||
@ -118,6 +119,8 @@ public interface AlarmService extends EntityDaoService {
 | 
			
		||||
    PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
 | 
			
		||||
                                                        AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
 | 
			
		||||
 | 
			
		||||
    void unassignUserAlarms(TenantId tenantId, UserId userId, long unassignTs);
 | 
			
		||||
 | 
			
		||||
    void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId);
 | 
			
		||||
 | 
			
		||||
    long countAlarmsByQuery(TenantId tenantId, CustomerId customerId, AlarmCountQuery query);
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,8 @@ public interface AlarmDao extends Dao<Alarm> {
 | 
			
		||||
 | 
			
		||||
    PageData<AlarmId> findAlarmsIdsByEndTsBeforeAndTenantId(Long time, TenantId tenantId, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    List<Alarm> findAlarmByAssigneeId(UUID key);
 | 
			
		||||
 | 
			
		||||
    void createEntityAlarmRecord(EntityAlarm entityAlarm);
 | 
			
		||||
 | 
			
		||||
    List<EntityAlarm> findEntityAlarmRecords(TenantId tenantId, AlarmId id);
 | 
			
		||||
 | 
			
		||||
@ -25,9 +25,12 @@ import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.springframework.util.CollectionUtils;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.Alarm;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmComment;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmCommentType;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.alarm.AlarmModificationRequest;
 | 
			
		||||
@ -84,6 +87,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
 | 
			
		||||
    private final TenantService tenantService;
 | 
			
		||||
    private final AlarmDao alarmDao;
 | 
			
		||||
    private final AlarmCommentDao alarmCommentDao;
 | 
			
		||||
    private final EntityService entityService;
 | 
			
		||||
    private final DataValidator<Alarm> alarmDataValidator;
 | 
			
		||||
 | 
			
		||||
@ -308,6 +312,28 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
        return withPropagated(alarmDao.unassignAlarm(tenantId, alarmId, unassignTime));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unassignUserAlarms(TenantId tenantId, UserId userId, long unassignTs) {
 | 
			
		||||
        List<Alarm> alarms = findAlarmsByAssigneeId(userId);
 | 
			
		||||
        for (Alarm alarm : alarms) {
 | 
			
		||||
            AlarmApiCallResult result = unassignAlarm(alarm.getTenantId(), alarm.getId(), unassignTs);
 | 
			
		||||
            if (!result.isSuccessful()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (result.isModified()) {
 | 
			
		||||
                AlarmComment alarmComment = AlarmComment.builder()
 | 
			
		||||
                        .alarmId(alarm.getId())
 | 
			
		||||
                        .type(AlarmCommentType.SYSTEM)
 | 
			
		||||
                        .comment(JacksonUtil.newObjectNode()
 | 
			
		||||
                                .put("text", "Alarm was unassigned because assigned user was deleted!")
 | 
			
		||||
                                .put("userId", userId.toString())
 | 
			
		||||
                                .put("subtype", "ASSIGN"))
 | 
			
		||||
                        .build();
 | 
			
		||||
                alarmCommentDao.save(tenantId, alarmComment);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Alarm findAlarmById(TenantId tenantId, AlarmId alarmId) {
 | 
			
		||||
        log.trace("Executing findAlarmById [{}]", alarmId);
 | 
			
		||||
@ -488,4 +514,10 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<Alarm> findAlarmsByAssigneeId(UserId userId) {
 | 
			
		||||
        log.trace("Executing findAlarmsByAssigneeId [{}]", userId);
 | 
			
		||||
        validateId(userId, "Incorrect alarmId " + userId);
 | 
			
		||||
        return alarmDao.findAlarmByAssigneeId(userId.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -315,6 +315,9 @@ public interface AlarmRepository extends JpaRepository<AlarmEntity, UUID> {
 | 
			
		||||
    @Query(value = "SELECT a FROM AlarmInfoEntity a WHERE a.tenantId = :tenantId AND a.id = :alarmId")
 | 
			
		||||
    AlarmInfoEntity findAlarmInfoById(@Param("tenantId") UUID tenantId, @Param("alarmId") UUID alarmId);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT a FROM AlarmEntity a WHERE a.assigneeId = :assigneeId")
 | 
			
		||||
    List<AlarmEntity> findAlarmByAssigneeId(@Param("assigneeId") UUID assigneeId);
 | 
			
		||||
 | 
			
		||||
    @Query(value = "SELECT create_or_update_active_alarm(:t_id, :c_id, :a_id, :a_created_ts, :a_o_id, :a_o_type, :a_type, :a_severity, " +
 | 
			
		||||
            ":a_start_ts, :a_end_ts, :a_details, :a_propagate, :a_propagate_to_owner, " +
 | 
			
		||||
            ":a_propagate_to_tenant, :a_propagation_types, :a_creation_enabled)", nativeQuery = true)
 | 
			
		||||
 | 
			
		||||
@ -285,6 +285,12 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
 | 
			
		||||
                .mapData(AlarmId::new);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Alarm> findAlarmByAssigneeId(UUID key) {
 | 
			
		||||
        List<AlarmEntity> assignedAlarms = alarmRepository.findAlarmByAssigneeId(key);
 | 
			
		||||
        return DaoUtil.convertDataList(assignedAlarms);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void createEntityAlarmRecord(EntityAlarm entityAlarm) {
 | 
			
		||||
        log.debug("Saving entity {}", entityAlarm);
 | 
			
		||||
 | 
			
		||||
@ -230,6 +230,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
 | 
			
		||||
    public void deleteUser(TenantId tenantId, UserId userId) {
 | 
			
		||||
        log.trace("Executing deleteUser [{}]", userId);
 | 
			
		||||
        validateId(userId, INCORRECT_USER_ID + userId);
 | 
			
		||||
        alarmService.unassignUserAlarms(tenantId, userId, System.currentTimeMillis());
 | 
			
		||||
        UserCredentials userCredentials = userCredentialsDao.findByUserId(tenantId, userId.getId());
 | 
			
		||||
        userCredentialsDao.removeById(tenantId, userCredentials.getUuidId());
 | 
			
		||||
        userAuthSettingsDao.removeByUserId(userId);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user