Browse Source

added alarm comment info object, refactoring

pull/7762/head
dashevchenko 4 years ago
parent
commit
201078714c
  1. 2
      application/src/main/data/upgrade/3.5/schema_update.sql
  2. 43
      application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java
  3. 6
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  4. 8
      application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java
  5. 4
      application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java
  6. 15
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java
  7. 5
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java
  8. 15
      application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
  9. 7
      common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java
  10. 15
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java
  11. 45
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java
  12. 7
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentDao.java
  13. 76
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java
  14. 97
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java
  15. 80
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java
  16. 41
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentInfoEntity.java
  17. 23
      dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java
  18. 16
      dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmCommentDataValidator.java
  19. 13
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmCommentRepository.java
  20. 17
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDao.java
  21. 2
      dao/src/main/resources/sql/schema-entities-idx.sql
  22. 10
      dao/src/main/resources/sql/schema-entities.sql

2
application/src/main/data/upgrade/3.5/schema_update.sql

@ -16,8 +16,6 @@
CREATE TABLE IF NOT EXISTS alarm_comment ( CREATE TABLE IF NOT EXISTS alarm_comment (
id uuid NOT NULL, id uuid NOT NULL,
tenant_id uuid NOT NULL,
customer_id uuid NOT NULL,
created_time bigint NOT NULL, created_time bigint NOT NULL,
alarm_id uuid NOT NULL, alarm_id uuid NOT NULL,
user_id uuid, user_id uuid,

43
application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java

@ -27,7 +27,9 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
@ -36,12 +38,15 @@ import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService;
import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ALARM_SORT_PROPERTY_ALLOWABLE_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK;
@ -69,10 +74,10 @@ public class AlarmCommentController extends BaseController {
public AlarmComment saveAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) public AlarmComment saveAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION)
@PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException {
checkParameter(ALARM_ID, strAlarmId); checkParameter(ALARM_ID, strAlarmId);
alarmComment.setTenantId(getTenantId()); AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
alarmComment.setAlarmId(new AlarmId(toUUID(strAlarmId))); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
checkEntity(alarmComment.getId(), alarmComment, Resource.ALARM_COMMENT); alarmComment.setAlarmId(alarmId);
return tbAlarmCommentService.saveAlarmComment(alarmComment, getCurrentUser()); return tbAlarmCommentService.saveAlarmComment(alarm.getTenantId(), alarmComment, getCurrentUser());
} }
@ApiOperation(value = "Delete Alarm comment(deleteAlarmComment)", @ApiOperation(value = "Delete Alarm comment(deleteAlarmComment)",
@ -82,9 +87,12 @@ public class AlarmCommentController extends BaseController {
@ResponseBody @ResponseBody
public Boolean deleteAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException { public Boolean deleteAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException {
checkParameter(ALARM_ID, strAlarmId); checkParameter(ALARM_ID, strAlarmId);
AlarmCommentId alarmCommentId = new AlarmCommentId(toUUID(strAlarmId)); AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
AlarmComment alarmComment = checkAlarmCommentId(alarmCommentId, Operation.DELETE); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
return tbAlarmCommentService.deleteAlarmComment(alarmComment, getCurrentUser());
AlarmCommentId alarmCommentId = new AlarmCommentId(toUUID(strCommentId));
AlarmComment alarmComment = checkAlarmCommentId(alarmCommentId);
return tbAlarmCommentService.deleteAlarmComment(alarm.getTenantId(), alarmComment, getCurrentUser());
} }
@ApiOperation(value = "Get Alarm comments (getAlarmComments)", @ApiOperation(value = "Get Alarm comments (getAlarmComments)",
@ -93,16 +101,23 @@ public class AlarmCommentController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.GET) @RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.GET)
@ResponseBody @ResponseBody
public PageData<AlarmComment> getAlarmComments( public PageData<AlarmCommentInfo> getAlarmComments(
@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION)
@PathVariable(ALARM_ID) String strAlarmCommentId, @PathVariable(ALARM_ID) String strAlarmId,
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize, @RequestParam int pageSize,
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
@RequestParam int page @RequestParam int page,
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortProperty,
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
@RequestParam(required = false) String sortOrder
) throws Exception { ) throws Exception {
AlarmId alarmId = new AlarmId(toUUID(strAlarmCommentId)); checkParameter(ALARM_ID, strAlarmId);
PageLink pageLink = createPageLink(pageSize, page, null, null, null); AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
return checkNotNull(alarmCommentService.findAlarmComments(alarmId, pageLink).get()); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
PageLink pageLink = createPageLink(pageSize, page, null, sortProperty, sortOrder);
return checkNotNull(alarmCommentService.findAlarmComments(alarm.getTenantId(), alarmId, pageLink).get());
} }
} }

6
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -536,9 +536,6 @@ public abstract class BaseController {
case ALARM: case ALARM:
checkAlarmId(new AlarmId(entityId.getId()), operation); checkAlarmId(new AlarmId(entityId.getId()), operation);
return; return;
case ALARM_COMMENT:
checkAlarmCommentId(new AlarmCommentId(entityId.getId()), operation);
return;
case DEVICE: case DEVICE:
checkDeviceId(new DeviceId(entityId.getId()), operation); checkDeviceId(new DeviceId(entityId.getId()), operation);
return; return;
@ -721,12 +718,11 @@ public abstract class BaseController {
} }
} }
AlarmComment checkAlarmCommentId(AlarmCommentId alarmCommentId, Operation operation) throws ThingsboardException { AlarmComment checkAlarmCommentId(AlarmCommentId alarmCommentId) throws ThingsboardException {
try { try {
validateId(alarmCommentId, "Incorrect alarmCommentId " + alarmCommentId); validateId(alarmCommentId, "Incorrect alarmCommentId " + alarmCommentId);
AlarmComment alarmComment = alarmCommentService.findAlarmCommentByIdAsync(getCurrentUser().getTenantId(), alarmCommentId).get(); AlarmComment alarmComment = alarmCommentService.findAlarmCommentByIdAsync(getCurrentUser().getTenantId(), alarmCommentId).get();
checkNotNull(alarmComment, "Alarm comment with id [" + alarmCommentId + "] is not found"); checkNotNull(alarmComment, "Alarm comment with id [" + alarmCommentId + "] is not found");
accessControlService.checkPermission(getCurrentUser(), Resource.ALARM_COMMENT, operation, alarmCommentId, alarmComment);
return alarmComment; return alarmComment;
} catch (Exception e) { } catch (Exception e) {
throw handleException(e, false); throw handleException(e, false);

8
application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java

@ -231,14 +231,14 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
} }
@Override @Override
public void notifyCreateOrUpdateAlarmComment(AlarmComment alarmComment, ActionType actionType, User user, Object... additionalInfo) { public void notifyCreateOrUpdateAlarmComment(TenantId tenantId, AlarmComment alarmComment, ActionType actionType, User user, Object... additionalInfo) {
logEntityAction(alarmComment.getTenantId(), alarmComment.getAlarmId(), alarmComment, alarmComment.getCustomerId(), actionType, user, additionalInfo); logEntityAction(tenantId, alarmComment.getAlarmId(), alarmComment, null, actionType, user, additionalInfo);
// TODO: should we send notification to edge? // TODO: should we send notification to edge?
} }
@Override @Override
public void notifyDeleteAlarmComment(AlarmComment alarmComment, User user, Object... additionalInfo) { public void notifyDeleteAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user, Object... additionalInfo) {
logEntityAction(alarmComment.getTenantId(), alarmComment.getAlarmId(), alarmComment, alarmComment.getCustomerId(), ActionType.DELETED, user, additionalInfo); logEntityAction(tenantId, alarmComment.getAlarmId(), alarmComment, null, ActionType.DELETED, user, additionalInfo);
// TODO: should we send notification to edge? // TODO: should we send notification to edge?
} }

4
application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java

@ -103,9 +103,9 @@ public interface TbNotificationEntityService {
void notifyCreateOrUpdateAlarm(Alarm alarm, ActionType actionType, User user, Object... additionalInfo); void notifyCreateOrUpdateAlarm(Alarm alarm, ActionType actionType, User user, Object... additionalInfo);
void notifyCreateOrUpdateAlarmComment(AlarmComment alarmComment, ActionType actionType, User user, Object... additionalInfo); void notifyCreateOrUpdateAlarmComment(TenantId tenantId, AlarmComment alarmComment, ActionType actionType, User user, Object... additionalInfo);
void notifyDeleteAlarmComment(AlarmComment alarmComment, User user, Object... additionalInfo); void notifyDeleteAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user, Object... additionalInfo);
<E extends HasName, I extends EntityId> void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId, <E extends HasName, I extends EntityId> void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId,
I entityId, E entity, User user, I entityId, E entity, User user,
ActionType actionType, boolean sendNotifyMsgToEdge, ActionType actionType, boolean sendNotifyMsgToEdge,

15
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java

@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
@ -29,22 +30,22 @@ import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
@AllArgsConstructor @AllArgsConstructor
public class DefaultTbAlarmCommentService extends AbstractTbEntityService implements TbAlarmCommentService{ public class DefaultTbAlarmCommentService extends AbstractTbEntityService implements TbAlarmCommentService{
@Override @Override
public AlarmComment saveAlarmComment(AlarmComment alarmComment, User user) throws ThingsboardException { public AlarmComment saveAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user) throws ThingsboardException {
ActionType actionType = alarmComment.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = alarmComment.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
UserId userId = user.getId(); UserId userId = user.getId();
alarmComment.setUserId(userId); alarmComment.setUserId(userId);
try { try {
AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.createOrUpdateAlarmComment(alarmComment).getAlarmComment()); AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment).getAlarmComment());
notificationEntityService.notifyCreateOrUpdateAlarmComment(savedAlarmComment, actionType, user); notificationEntityService.notifyCreateOrUpdateAlarmComment(tenantId, savedAlarmComment, actionType, user);
return savedAlarmComment; return savedAlarmComment;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(alarmComment.getTenantId(), emptyId(EntityType.ALARM_COMMENT), alarmComment, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ALARM_COMMENT), alarmComment, actionType, user, e);
throw e; throw e;
} }
} }
@Override @Override
public Boolean deleteAlarmComment(AlarmComment alarmComment, User user) { public Boolean deleteAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user) {
notificationEntityService.notifyDeleteAlarmComment(alarmComment, user); notificationEntityService.notifyDeleteAlarmComment(tenantId, alarmComment, user);
return alarmCommentService.deleteAlarmComment(alarmComment.getId()).isSuccessful(); return alarmCommentService.deleteAlarmComment(tenantId, alarmComment.getId()).isSuccessful();
} }
} }

5
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java

@ -18,9 +18,10 @@ package org.thingsboard.server.service.entitiy.alarm;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
public interface TbAlarmCommentService { public interface TbAlarmCommentService {
AlarmComment saveAlarmComment(AlarmComment alarmComment, User user) throws ThingsboardException; AlarmComment saveAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user) throws ThingsboardException;
Boolean deleteAlarmComment(AlarmComment alarmComment, User user); Boolean deleteAlarmComment(TenantId tenantId, AlarmComment alarmComment, User user);
} }

15
application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java

@ -32,7 +32,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
public CustomerUserPermissions() { public CustomerUserPermissions() {
super(); super();
put(Resource.ALARM, customerAlarmPermissionChecker); put(Resource.ALARM, customerAlarmPermissionChecker);
put(Resource.ALARM_COMMENT, customerAlarmCommentPermissionChecker); put(Resource.ALARM_COMMENT, customerAlarmPermissionChecker);
put(Resource.ASSET, customerEntityPermissionChecker); put(Resource.ASSET, customerEntityPermissionChecker);
put(Resource.DEVICE, customerEntityPermissionChecker); put(Resource.DEVICE, customerEntityPermissionChecker);
put(Resource.CUSTOMER, customerPermissionChecker); put(Resource.CUSTOMER, customerPermissionChecker);
@ -60,19 +60,6 @@ public class CustomerUserPermissions extends AbstractPermissions {
} }
}; };
private static final PermissionChecker customerAlarmCommentPermissionChecker = new PermissionChecker() {
@Override
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!user.getTenantId().equals(entity.getTenantId())) {
return false;
}
if (!(entity instanceof HasCustomerId)) {
return false;
}
return user.getCustomerId().equals(((HasCustomerId) entity).getCustomerId());
}
};
private static final PermissionChecker customerEntityPermissionChecker = private static final PermissionChecker customerEntityPermissionChecker =
new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_CREDENTIALS, new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_CREDENTIALS,
Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY, Operation.RPC_CALL, Operation.CLAIM_DEVICES, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY, Operation.RPC_CALL, Operation.CLAIM_DEVICES,

7
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.alarm;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -24,11 +25,11 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
public interface AlarmCommentService { public interface AlarmCommentService {
AlarmCommentOperationResult createOrUpdateAlarmComment(AlarmComment alarmComment); AlarmCommentOperationResult createOrUpdateAlarmComment(TenantId tenantId, AlarmComment alarmComment);
AlarmCommentOperationResult deleteAlarmComment(AlarmCommentId alarmCommentId); AlarmCommentOperationResult deleteAlarmComment(TenantId tenantId, AlarmCommentId alarmCommentId);
ListenableFuture<PageData<AlarmComment>> findAlarmComments(AlarmId alarmId, PageLink pageLink); ListenableFuture<PageData<AlarmCommentInfo>> findAlarmComments(TenantId tenantId, AlarmId alarmId, PageLink pageLink);
ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, AlarmCommentId alarmCommentId); ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, AlarmCommentId alarmCommentId);

15
common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java

@ -22,25 +22,16 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
@ApiModel @ApiModel
@Data @Data
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
public class AlarmComment extends BaseData<AlarmCommentId> implements HasName, HasTenantId, HasCustomerId { public class AlarmComment extends BaseData<AlarmCommentId> implements HasName {
@ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private TenantId tenantId;
@ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private CustomerId customerId;
@ApiModelProperty(position = 2, value = "JSON object with Alarm id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @ApiModelProperty(position = 2, value = "JSON object with Alarm id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private EntityId alarmId; private EntityId alarmId;
@ApiModelProperty(position = 3, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @ApiModelProperty(position = 3, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
@ -81,11 +72,9 @@ public class AlarmComment extends BaseData<AlarmCommentId> implements HasName, H
public AlarmComment(AlarmComment alarmComment) { public AlarmComment(AlarmComment alarmComment) {
super(alarmComment.getId()); super(alarmComment.getId());
this.createdTime = alarmComment.getCreatedTime(); this.createdTime = alarmComment.getCreatedTime();
this.tenantId = alarmComment.getTenantId(); this.alarmId = alarmComment.getAlarmId();
this.customerId = alarmComment.getCustomerId();
this.type = alarmComment.getType(); this.type = alarmComment.getType();
this.comment = alarmComment.getComment(); this.comment = alarmComment.getComment();
this.userId = alarmComment.getUserId(); this.userId = alarmComment.getUserId();
} }
} }

45
common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java

@ -22,8 +22,11 @@ import io.swagger.annotations.ApiModelProperty;
public class AlarmCommentInfo extends AlarmComment{ public class AlarmCommentInfo extends AlarmComment{
private static final long serialVersionUID = 2807343093519543377L; private static final long serialVersionUID = 2807343093519543377L;
@ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat") @ApiModelProperty(position = 19, value = "User name", example = "John")
private String userName; private String firstName;
@ApiModelProperty(position = 19, value = "User name", example = "Brown")
private String lastName;
public AlarmCommentInfo() { public AlarmCommentInfo() {
super(); super();
@ -33,17 +36,26 @@ public class AlarmCommentInfo extends AlarmComment{
super(alarmComment); super(alarmComment);
} }
public AlarmCommentInfo(AlarmComment alarmComment, String userName) { public AlarmCommentInfo(AlarmComment alarmComment, String firstName, String lastName) {
super(alarmComment); super(alarmComment);
this.userName = userName; this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
} }
public String getUserName() { public void setFirstName(String firstName) {
return userName; this.firstName = firstName;
} }
public void setOriginatorName(String originatorName) { public String getLastName() {
this.userName = originatorName; return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
} }
@Override @Override
@ -54,14 +66,27 @@ public class AlarmCommentInfo extends AlarmComment{
AlarmCommentInfo alarmCommentInfo = (AlarmCommentInfo) o; AlarmCommentInfo alarmCommentInfo = (AlarmCommentInfo) o;
return userName != null ? userName.equals(alarmCommentInfo.userName) : alarmCommentInfo.userName == null; if (firstName == null) {
if (alarmCommentInfo.firstName != null)
return false;
} else if (!firstName.equals(alarmCommentInfo.firstName))
return false;
if (lastName == null) {
if (alarmCommentInfo.lastName != null)
return false;
} else if (!lastName.equals(alarmCommentInfo.lastName))
return false;
return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = super.hashCode(); int result = super.hashCode();
result = 31 * result + (userName != null ? userName.hashCode() : 0); result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
return result; return result;
} }
} }

7
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentDao.java

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.alarm;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -27,12 +28,12 @@ import org.thingsboard.server.dao.Dao;
import java.util.UUID; import java.util.UUID;
public interface AlarmCommentDao extends Dao<AlarmComment> { public interface AlarmCommentDao extends Dao<AlarmComment> {
AlarmComment createAlarmComment(AlarmComment alarmComment); AlarmComment createAlarmComment(TenantId tenantId, AlarmComment alarmComment);
void deleteAlarmComment(AlarmCommentId alarmCommentId); void deleteAlarmComment(TenantId tenantId, AlarmCommentId alarmCommentId);
AlarmComment findAlarmCommentById(TenantId tenantId, UUID key); AlarmComment findAlarmCommentById(TenantId tenantId, UUID key);
PageData<AlarmComment> findAlarmComments(AlarmId id, PageLink pageLink); PageData<AlarmCommentInfo> findAlarmComments(TenantId tenantId, AlarmId id, PageLink pageLink);
ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, UUID key); ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, UUID key);

76
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java

@ -15,13 +15,18 @@
*/ */
package org.thingsboard.server.dao.alarm; package org.thingsboard.server.dao.alarm;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -30,6 +35,11 @@ import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.user.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;
@ -40,33 +50,50 @@ public class BaseAlarmCommentService extends AbstractEntityService implements Al
@Autowired @Autowired
private AlarmCommentDao alarmCommentDao; private AlarmCommentDao alarmCommentDao;
@Autowired @Autowired
private UserService userService;
@Autowired
private EntityService entityService; private EntityService entityService;
@Autowired @Autowired
private DataValidator<AlarmComment> alarmCommentDataValidator; private DataValidator<AlarmComment> alarmCommentDataValidator;
@Override @Override
public AlarmCommentOperationResult createOrUpdateAlarmComment(AlarmComment alarmComment) { public AlarmCommentOperationResult createOrUpdateAlarmComment(TenantId tenantId, AlarmComment alarmComment) {
alarmCommentDataValidator.validate(alarmComment, AlarmComment::getTenantId); alarmCommentDataValidator.validate(alarmComment, tenantId);
alarmComment.setCustomerId(entityService.fetchEntityCustomerId(alarmComment.getTenantId(), alarmComment.getAlarmId()));
if (alarmComment.getId() == null) { if (alarmComment.getId() == null) {
return createAlarmComment(alarmComment); return createAlarmComment(tenantId, alarmComment);
} else { } else {
return updateAlarmComment(alarmComment); return updateAlarmComment(tenantId, alarmComment);
} }
} }
@Override @Override
@Transactional @Transactional
public AlarmCommentOperationResult deleteAlarmComment(AlarmCommentId alarmCommentId) { public AlarmCommentOperationResult deleteAlarmComment(TenantId tenantId, AlarmCommentId alarmCommentId) {
log.debug("Deleting Alarm Comment with id: {}", alarmCommentId); log.debug("Deleting Alarm Comment with id: {}", alarmCommentId);
AlarmCommentOperationResult result = new AlarmCommentOperationResult(new AlarmComment(), true); AlarmCommentOperationResult result = new AlarmCommentOperationResult(new AlarmComment(), true);
alarmCommentDao.deleteAlarmComment(alarmCommentId); alarmCommentDao.deleteAlarmComment(tenantId, alarmCommentId);
return result; return result;
} }
@Override @Override
public ListenableFuture<PageData<AlarmComment>> findAlarmComments(AlarmId alarmId, PageLink pageLink) { public ListenableFuture<PageData<AlarmCommentInfo>> findAlarmComments(TenantId tenantId, AlarmId alarmId, PageLink pageLink) {
PageData<AlarmComment> alarmComments = alarmCommentDao.findAlarmComments(alarmId, pageLink); PageData<AlarmCommentInfo> alarmComments = alarmCommentDao.findAlarmComments(tenantId, alarmId, pageLink);
return Futures.immediateFuture(alarmComments); return fetchAlarmCommentUserNames(tenantId,alarmComments);
}
private ListenableFuture<PageData<AlarmCommentInfo>> fetchAlarmCommentUserNames(TenantId tenantId, PageData<AlarmCommentInfo> alarmComments) {
List<ListenableFuture<AlarmCommentInfo>> alarmCommentFutures = new ArrayList<>(alarmComments.getData().size());
for (AlarmCommentInfo alarmCommentInfo : alarmComments.getData()) {
alarmCommentFutures.add(Futures.transform(
userService.findUserByIdAsync(tenantId, alarmCommentInfo.getUserId()), user -> {
alarmCommentInfo.setFirstName(user.getFirstName());
alarmCommentInfo.setLastName(user.getLastName());
return alarmCommentInfo;
}, MoreExecutors.directExecutor()
));
}
return Futures.transform(Futures.successfulAsList(alarmCommentFutures),
alarmCommentInfos -> new PageData<>(alarmCommentInfos, alarmComments.getTotalPages(), alarmComments.getTotalElements(),
alarmComments.hasNext()), MoreExecutors.directExecutor());
} }
@Override @Override
@ -76,30 +103,35 @@ public class BaseAlarmCommentService extends AbstractEntityService implements Al
return alarmCommentDao.findAlarmCommentByIdAsync(tenantId, alarmCommentId.getId()); return alarmCommentDao.findAlarmCommentByIdAsync(tenantId, alarmCommentId.getId());
} }
private AlarmCommentOperationResult createAlarmComment(AlarmComment alarmComment) { private AlarmCommentOperationResult createAlarmComment(TenantId tenantId, AlarmComment alarmComment) {
log.debug("New Alarm comment : {}", alarmComment); log.debug("New Alarm comment : {}", alarmComment);
if (alarmComment.getType() == null) { if (alarmComment.getType() == null) {
alarmComment.setType("OTHER"); alarmComment.setType("OTHER");
} }
AlarmComment saved = alarmCommentDao.createAlarmComment(alarmComment); if (alarmComment.getId() == null) {
UUID uuid = Uuids.timeBased();
alarmComment.setId(new AlarmCommentId(uuid));
alarmComment.setCreatedTime(Uuids.unixTimestamp(uuid));
}
AlarmComment saved = alarmCommentDao.createAlarmComment(tenantId, alarmComment);
return new AlarmCommentOperationResult(saved, true, true); return new AlarmCommentOperationResult(saved, true, true);
} }
private AlarmCommentOperationResult updateAlarmComment(AlarmComment newAlarmComment) { private AlarmCommentOperationResult updateAlarmComment(TenantId tenantId, AlarmComment newAlarmComment) {
log.debug("Update Alarm comment : {}", newAlarmComment); log.debug("Update Alarm comment : {}", newAlarmComment);
validateId(newAlarmComment.getId(), "Alarm comment id should be specified!"); AlarmComment existing = alarmCommentDao.findAlarmCommentById(tenantId, newAlarmComment.getId().getId());
AlarmComment existing = alarmCommentDao.findAlarmCommentById(newAlarmComment.getTenantId(), newAlarmComment.getId().getId());
if (existing != null) { if (existing != null) {
AlarmComment result = alarmCommentDao.save(newAlarmComment.getTenantId(), merge(existing, newAlarmComment)); if (newAlarmComment.getComment() != null) {
JsonNode comment = newAlarmComment.getComment();
UUID uuid = Uuids.timeBased();
((ObjectNode) comment).put("edited", "true");
((ObjectNode) comment).put("editedOn", Uuids.unixTimestamp(uuid));
existing.setComment(comment);
}
AlarmComment result = alarmCommentDao.save(tenantId, existing);
return new AlarmCommentOperationResult(result, true, true); return new AlarmCommentOperationResult(result, true, true);
} }
return null; return null;
} }
private AlarmComment merge(AlarmComment existing, AlarmComment alarmComment) {
existing.setCustomerId(alarmComment.getCustomerId());
existing.setComment(alarmComment.getComment());
return existing;
}
} }

97
dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java

@ -0,0 +1,97 @@
/**
* 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.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_ALARM_ID;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_COMMENT;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TYPE;
@Data
@EqualsAndHashCode(callSuper = true)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@MappedSuperclass
public abstract class AbstractAlarmCommentEntity<T extends AlarmComment> extends BaseSqlEntity<T> implements BaseEntity<T> {
@Column(name = ALARM_COMMENT_ALARM_ID, columnDefinition = "uuid")
private UUID alarmId;
@Column(name = ModelConstants.ALARM_COMMENT_USER_ID)
private UUID userId;
@Column(name = ALARM_COMMENT_TYPE)
private String type;
@Type(type = "json")
@Column(name = ALARM_COMMENT_COMMENT)
private JsonNode comment;
public AbstractAlarmCommentEntity() {
super();
}
public AbstractAlarmCommentEntity(AlarmComment alarmComment) {
if (alarmComment.getId() != null) {
this.setUuid(alarmComment.getUuidId());
}
this.setCreatedTime(alarmComment.getCreatedTime());
if (alarmComment.getAlarmId() != null) {
this.alarmId = alarmComment.getAlarmId().getId();
}
if (alarmComment.getUserId() != null) {
this.userId = alarmComment.getUserId().getId();
}
if (alarmComment.getType() != null) {
this.type = alarmComment.getType();
}
this.setComment(alarmComment.getComment());
}
public AbstractAlarmCommentEntity(AlarmCommentEntity alarmCommentEntity) {
this.setId(alarmCommentEntity.getId());
this.setCreatedTime(alarmCommentEntity.getCreatedTime());
this.userId = alarmCommentEntity.getUserId();
this.alarmId = alarmCommentEntity.getAlarmId();
this.type = alarmCommentEntity.getType();
this.comment = alarmCommentEntity.getComment();
}
protected AlarmComment toAlarmComment() {
AlarmComment alarmComment = new AlarmComment(new AlarmCommentId(id));
alarmComment.setCreatedTime(createdTime);
alarmComment.setAlarmId(new AlarmId(alarmId));
alarmComment.setUserId(new UserId(userId));
alarmComment.setType(type);
alarmComment.setComment(comment);
return alarmComment;
}
}

80
dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java

@ -15,33 +15,17 @@
*/ */
package org.thingsboard.server.dao.model.sql; package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonStringType; import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_ALARM_ID;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_COLUMN_FAMILY_NAME; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_COMMENT;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TYPE;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -49,71 +33,23 @@ import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TYPE
@TypeDef(name = "json", typeClass = JsonStringType.class) @TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ALARM_COMMENT_COLUMN_FAMILY_NAME) @Table(name = ALARM_COMMENT_COLUMN_FAMILY_NAME)
public class AlarmCommentEntity extends BaseSqlEntity<AlarmComment> implements BaseEntity<AlarmComment> { public class AlarmCommentEntity extends AbstractAlarmCommentEntity<AlarmComment> {
@Column(name = ALARM_COMMENT_TENANT_ID_PROPERTY, columnDefinition = "uuid")
private UUID tenantId;
@Column(name = ALARM_COMMENT_CUSTOMER_ID_PROPERTY, columnDefinition = "uuid")
private UUID customerId;
@Column(name = ALARM_COMMENT_ALARM_ID, columnDefinition = "uuid")
private UUID alarmId;
@Column(name = ModelConstants.ALARM_COMMENT_USER_ID)
private UUID userId;
@Column(name = ALARM_COMMENT_TYPE)
private String type;
@Type(type = "json")
@Column(name = ALARM_COMMENT_COMMENT)
private JsonNode comment;
public AlarmCommentEntity() { public AlarmCommentEntity() {
super(); super();
} }
public AlarmCommentEntity(AlarmCommentInfo alarmCommentInfo) {
super(alarmCommentInfo);
}
public AlarmCommentEntity(AlarmComment alarmComment) { public AlarmCommentEntity(AlarmComment alarmComment) {
if (alarmComment.getId() != null) { super(alarmComment);
this.setUuid(alarmComment.getUuidId());
}
if (alarmComment.getTenantId() != null) {
this.tenantId = alarmComment.getTenantId().getId();
}
if (alarmComment.getCustomerId() != null) {
this.customerId = alarmComment.getCustomerId().getId();
}
this.setCreatedTime(alarmComment.getCreatedTime());
this.setCreatedTime(alarmComment.getCreatedTime());
if (alarmComment.getAlarmId() != null) {
this.alarmId = alarmComment.getAlarmId().getId();
}
if (alarmComment.getUserId() != null) {
this.userId = alarmComment.getUserId().getId();
}
if (alarmComment.getType() != null) {
this.type = alarmComment.getType();
}
this.setComment(alarmComment.getComment());
} }
@Override @Override
public AlarmComment toData() { public AlarmComment toData() {
AlarmComment alarmComment = new AlarmComment(new AlarmCommentId(id)); return super.toAlarmComment();
alarmComment.setCreatedTime(createdTime);
alarmComment.setAlarmId(new AlarmId(alarmId));
if (userId != null) {
alarmComment.setUserId(new UserId(userId));
}
if (tenantId != null) {
alarmComment.setTenantId(TenantId.fromUUID(tenantId));
}
if (customerId != null) {
alarmComment.setCustomerId(new CustomerId(customerId));
}
alarmComment.setType(type);
alarmComment.setComment(comment);
return alarmComment;
} }
} }

41
dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentInfoEntity.java

@ -0,0 +1,41 @@
/**
* 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.dao.model.sql;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
@Data
@EqualsAndHashCode(callSuper = true)
public class AlarmCommentInfoEntity extends AbstractAlarmCommentEntity<AlarmCommentInfo> {
private String firstName;
private String lastName;
public AlarmCommentInfoEntity() {
super();
}
public AlarmCommentInfoEntity(AlarmCommentEntity alarmCommentEntity) {
super(alarmCommentEntity);
}
@Override
public AlarmCommentInfo toData() {
return new AlarmCommentInfo(super.toAlarmComment(), this.firstName, this.lastName);
}
}

23
dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java

@ -67,6 +67,29 @@ public abstract class DataValidator<D extends BaseData<?>> {
} }
} }
public D validate(D data, TenantId tenantId) {
try {
if (data == null) {
throw new DataValidationException("Data object can't be null!");
}
ConstraintValidator.validateFields(data);
validateDataImpl(tenantId, data);
D old;
if (data.getId() == null) {
validateCreate(tenantId, data);
old = null;
} else {
old = validateUpdate(tenantId, data);
}
return old;
} catch (DataValidationException e) {
log.error("{} object is invalid: [{}]", data == null ? "Data" : data.getClass().getSimpleName(), e.getMessage());
throw e;
}
}
protected void validateDataImpl(TenantId tenantId, D data) { protected void validateDataImpl(TenantId tenantId, D data) {
} }

16
dao/src/main/java/org/thingsboard/server/dao/service/validator/AlarmCommentDataValidator.java

@ -17,28 +17,22 @@ package org.thingsboard.server.dao.service.validator;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantService;
@Component @Component
@AllArgsConstructor @AllArgsConstructor
public class AlarmCommentDataValidator extends DataValidator<AlarmComment> { public class AlarmCommentDataValidator extends DataValidator<AlarmComment> {
private final TenantService tenantService;
@Override @Override
protected void validateDataImpl(TenantId tenantId, AlarmComment alarmComment) { protected void validateDataImpl(TenantId tenantId, AlarmComment alarmComment) {
if (alarmComment.getTenantId() == null) { if (alarmComment.getComment() == null) {
throw new DataValidationException("Alarm comment should be assigned to tenant!"); throw new DataValidationException("Alarm comment should be specified!");
} else { }
if (!tenantService.tenantExists(alarmComment.getTenantId())) { if (alarmComment.getAlarmId() == null) {
throw new DataValidationException("Alarm comment is referencing to non-existent tenant!"); throw new DataValidationException("Alarm id should be specified!");
}
} }
} }
} }

13
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmCommentRepository.java

@ -18,12 +18,21 @@ package org.thingsboard.server.dao.sql.alarm;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.AlarmCommentEntity; import org.thingsboard.server.dao.model.sql.AlarmCommentEntity;
import org.thingsboard.server.dao.model.sql.AlarmCommentInfoEntity;
import java.util.UUID; import java.util.UUID;
public interface AlarmCommentRepository extends JpaRepository<AlarmCommentEntity, UUID> { public interface AlarmCommentRepository extends JpaRepository<AlarmCommentEntity, UUID> {
Page<AlarmCommentEntity> findAllByAlarmId(UUID alarmId, Pageable pageable); @Query(value = "SELECT new org.thingsboard.server.dao.model.sql.AlarmCommentInfoEntity(a) FROM AlarmCommentEntity a " +
"WHERE a.alarmId = :alarmId ",
countQuery = "" +
"SELECT count(a) " +
"FROM AlarmCommentEntity a " +
"WHERE a.alarmId = :alarmId ")
Page<AlarmCommentInfoEntity> findAllByAlarmId(@Param("alarmId") UUID alarmId,
Pageable pageable);
} }

17
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDao.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.dao.sql.alarm; package org.thingsboard.server.dao.sql.alarm;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -24,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo;
import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmCommentId;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -54,34 +54,29 @@ public class JpaAlarmCommentDao extends JpaAbstractDao<AlarmCommentEntity, Alarm
private AlarmCommentRepository alarmCommentRepository; private AlarmCommentRepository alarmCommentRepository;
@Override @Override
public AlarmComment createAlarmComment(AlarmComment alarmComment){ public AlarmComment createAlarmComment(TenantId tenantId, AlarmComment alarmComment){
log.debug("Saving entity {}", alarmComment); log.debug("Saving entity {}", alarmComment);
if (alarmComment.getId() == null) {
UUID uuid = Uuids.timeBased();
alarmComment.setId(new AlarmCommentId(uuid));
alarmComment.setCreatedTime(Uuids.unixTimestamp(uuid));
}
partitioningRepository.createPartitionIfNotExists(ALARM_COMMENT_COLUMN_FAMILY_NAME, alarmComment.getCreatedTime(), TimeUnit.HOURS.toMillis(partitionSizeInHours)); partitioningRepository.createPartitionIfNotExists(ALARM_COMMENT_COLUMN_FAMILY_NAME, alarmComment.getCreatedTime(), TimeUnit.HOURS.toMillis(partitionSizeInHours));
AlarmCommentEntity saved = alarmCommentRepository.save(new AlarmCommentEntity(alarmComment)); AlarmCommentEntity saved = alarmCommentRepository.save(new AlarmCommentEntity(alarmComment));
return DaoUtil.getData(saved); return DaoUtil.getData(saved);
} }
@Override @Override
public void deleteAlarmComment(AlarmCommentId alarmCommentId){ public void deleteAlarmComment(TenantId tenantId, AlarmCommentId alarmCommentId){
log.trace("Try to delete entity alarm comment by id using [{}]", alarmCommentId); log.trace("Try to delete entity alarm comment by id using [{}]", alarmCommentId);
alarmCommentRepository.deleteById(alarmCommentId.getId()); alarmCommentRepository.deleteById(alarmCommentId.getId());
} }
@Override @Override
public PageData<AlarmComment> findAlarmComments(AlarmId id, PageLink pageLink){ public PageData<AlarmCommentInfo> findAlarmComments(TenantId tenantId, AlarmId id, PageLink pageLink){
log.trace("Try to find alarm comments by alard id using [{}]", id); log.trace("Try to find alarm comments by alard id using [{}]", id);
return DaoUtil.toPageData( return DaoUtil.toPageData(
alarmCommentRepository.findAllByAlarmId(id.getId(), DaoUtil.toPageable(pageLink))); alarmCommentRepository.findAllByAlarmId(id.getId(), DaoUtil.toPageable(pageLink)));
} }
@Override
public AlarmComment findAlarmCommentById(TenantId tenantId, UUID key) { public AlarmComment findAlarmCommentById(TenantId tenantId, UUID key) {
return findById(tenantId, key); return DaoUtil.getData(alarmCommentRepository.findById(key));
} }
@Override @Override

2
dao/src/main/resources/sql/schema-entities-idx.sql

@ -75,3 +75,5 @@ CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id,
CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type);
CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id);
CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id ASC);

10
dao/src/main/resources/sql/schema-entities.sql

@ -776,3 +776,13 @@ CREATE TABLE IF NOT EXISTS user_auth_settings (
user_id uuid UNIQUE NOT NULL CONSTRAINT fk_user_auth_settings_user_id REFERENCES tb_user(id), user_id uuid UNIQUE NOT NULL CONSTRAINT fk_user_auth_settings_user_id REFERENCES tb_user(id),
two_fa_settings varchar two_fa_settings varchar
); );
REATE TABLE IF NOT EXISTS alarm_comment (
id uuid NOT NULL,
created_time bigint NOT NULL,
alarm_id uuid NOT NULL,
user_id uuid,
type varchar(255) NOT NULL,
comment varchar(1000000),
CONSTRAINT fk_alarm_comment_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE
) PARTITION BY RANGE (created_time);
Loading…
Cancel
Save