32 changed files with 1016 additions and 3 deletions
@ -0,0 +1,28 @@ |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS alarm_comment ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
customer_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); |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id ASC); |
|||
@ -0,0 +1,108 @@ |
|||
/** |
|||
* 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.controller; |
|||
|
|||
import io.swagger.annotations.ApiOperation; |
|||
import io.swagger.annotations.ApiParam; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.PathVariable; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestMethod; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.id.AlarmCommentId; |
|||
import org.thingsboard.server.common.data.id.AlarmId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; |
|||
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.PAGE_DATA_PARAMETERS; |
|||
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.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; |
|||
import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; |
|||
|
|||
@RestController |
|||
@TbCoreComponent |
|||
@RequiredArgsConstructor |
|||
@RequestMapping("/api") |
|||
public class AlarmCommentController extends BaseController { |
|||
public static final String ALARM_ID = "alarmId"; |
|||
public static final String ALARM_COMMENT_ID = "commentId"; |
|||
|
|||
private final TbAlarmCommentService tbAlarmCommentService; |
|||
|
|||
@ApiOperation(value = "Create or update Alarm Comment ", |
|||
notes = "Creates or Updates the Alarm Comment. " + |
|||
"When creating comment, platform generates Alarm Comment Id as " + UUID_WIKI_LINK + |
|||
"The newly created Alarm Comment id will be present in the response. Specify existing Alarm Comment id to update the alarm. " + |
|||
"Referencing non-existing Alarm Comment Id will cause 'Not Found' error. " + |
|||
"\nRemove 'id' and optionally 'userId' from the request body example (below) to create new Alarm comment entity. " + |
|||
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH |
|||
, produces = MediaType.APPLICATION_JSON_VALUE) |
|||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
|||
@RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.POST) |
|||
@ResponseBody |
|||
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 { |
|||
checkParameter(ALARM_ID, strAlarmId); |
|||
alarmComment.setTenantId(getTenantId()); |
|||
alarmComment.setAlarmId(new AlarmId(toUUID(strAlarmId))); |
|||
checkEntity(alarmComment.getId(), alarmComment, Resource.ALARM_COMMENT); |
|||
return tbAlarmCommentService.saveAlarmComment(alarmComment, getCurrentUser()); |
|||
} |
|||
|
|||
@ApiOperation(value = "Delete Alarm comment(deleteAlarmComment)", |
|||
notes = "Deletes the Alarm comment. Referencing non-existing Alarm comment Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) |
|||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
|||
@RequestMapping(value = "/alarm/{alarmId}/comment/{commentId}", method = RequestMethod.DELETE) |
|||
@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 { |
|||
checkParameter(ALARM_ID, strAlarmId); |
|||
AlarmCommentId alarmCommentId = new AlarmCommentId(toUUID(strAlarmId)); |
|||
AlarmComment alarmComment = checkAlarmCommentId(alarmCommentId, Operation.DELETE); |
|||
return tbAlarmCommentService.deleteAlarmComment(alarmComment, getCurrentUser()); |
|||
} |
|||
|
|||
@ApiOperation(value = "Get Alarm comments (getAlarmComments)", |
|||
notes = "Returns a page of alarm comments. " + |
|||
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) |
|||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
|||
@RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.GET) |
|||
@ResponseBody |
|||
public PageData<AlarmComment> getAlarmComments( |
|||
@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) |
|||
@PathVariable(ALARM_ID) String strAlarmCommentId, |
|||
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) |
|||
@RequestParam int pageSize, |
|||
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) |
|||
@RequestParam int page |
|||
) throws Exception { |
|||
AlarmId alarmId = new AlarmId(toUUID(strAlarmCommentId)); |
|||
PageLink pageLink = createPageLink(pageSize, page, null, null, null); |
|||
return checkNotNull(alarmCommentService.findAlarmComments(alarmId, pageLink).get()); |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.id.UserId; |
|||
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
|||
|
|||
@Service |
|||
@AllArgsConstructor |
|||
public class DefaultTbAlarmCommentService extends AbstractTbEntityService implements TbAlarmCommentService{ |
|||
@Override |
|||
public AlarmComment saveAlarmComment(AlarmComment alarmComment, User user) throws ThingsboardException { |
|||
ActionType actionType = alarmComment.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
|||
UserId userId = user.getId(); |
|||
alarmComment.setUserId(userId); |
|||
try { |
|||
AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.createOrUpdateAlarmComment(alarmComment).getAlarmComment()); |
|||
notificationEntityService.notifyCreateOrUpdateAlarmComment(savedAlarmComment, actionType, user); |
|||
return savedAlarmComment; |
|||
} catch (Exception e) { |
|||
notificationEntityService.logEntityAction(alarmComment.getTenantId(), emptyId(EntityType.ALARM_COMMENT), alarmComment, actionType, user, e); |
|||
throw e; |
|||
} |
|||
} |
|||
@Override |
|||
public Boolean deleteAlarmComment(AlarmComment alarmComment, User user) { |
|||
notificationEntityService.notifyDeleteAlarmComment(alarmComment, user); |
|||
return alarmCommentService.deleteAlarmComment(alarmComment.getId()).isSuccessful(); |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
|
|||
public interface TbAlarmCommentService { |
|||
AlarmComment saveAlarmComment(AlarmComment alarmComment, User user) throws ThingsboardException; |
|||
|
|||
Boolean deleteAlarmComment(AlarmComment alarmComment, User user); |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import lombok.Data; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
|
|||
@Data |
|||
public class AlarmCommentOperationResult { |
|||
private final AlarmComment alarmComment; |
|||
private final boolean successful; |
|||
private final boolean created; |
|||
|
|||
|
|||
public AlarmCommentOperationResult(AlarmComment alarmComment, boolean successful) { |
|||
this(alarmComment, successful, false); |
|||
} |
|||
|
|||
public AlarmCommentOperationResult(AlarmComment alarmComment, boolean successful, boolean created) { |
|||
this.alarmComment = alarmComment; |
|||
this.successful = successful; |
|||
this.created = created; |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
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.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
|
|||
public interface AlarmCommentService { |
|||
AlarmCommentOperationResult createOrUpdateAlarmComment(AlarmComment alarmComment); |
|||
|
|||
AlarmCommentOperationResult deleteAlarmComment(AlarmCommentId alarmCommentId); |
|||
|
|||
ListenableFuture<PageData<AlarmComment>> findAlarmComments(AlarmId alarmId, PageLink pageLink); |
|||
|
|||
ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, AlarmCommentId alarmCommentId); |
|||
|
|||
} |
|||
@ -0,0 +1,91 @@ |
|||
/** |
|||
* 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.common.data.alarm; |
|||
|
|||
import com.fasterxml.jackson.databind.JsonNode; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
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.HasTenantId; |
|||
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.TenantId; |
|||
import org.thingsboard.server.common.data.id.UserId; |
|||
|
|||
@ApiModel |
|||
@Data |
|||
@Builder |
|||
@AllArgsConstructor |
|||
public class AlarmComment extends BaseData<AlarmCommentId> implements HasName, HasTenantId, HasCustomerId { |
|||
@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) |
|||
private EntityId alarmId; |
|||
@ApiModelProperty(position = 3, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) |
|||
private UserId userId; |
|||
@ApiModelProperty(position = 4, value = "Defines origination of comment", example = "System/Other", accessMode = ApiModelProperty.AccessMode.READ_ONLY) |
|||
private String type; |
|||
@ApiModelProperty(position = 5, value = "JSON object with text of comment.", dataType = "com.fasterxml.jackson.databind.JsonNode") |
|||
private transient JsonNode comment; |
|||
|
|||
@ApiModelProperty(position = 1, value = "JSON object with the alarm comment Id. " + |
|||
"Specify this field to update the alarm comment. " + |
|||
"Referencing non-existing alarm Id will cause error. " + |
|||
"Omit this field to create new alarm." ) |
|||
@Override |
|||
public AlarmCommentId getId() { |
|||
return super.getId(); |
|||
} |
|||
|
|||
@ApiModelProperty(position = 2, value = "Timestamp of the alarm comment creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) |
|||
@Override |
|||
public long getCreatedTime() { |
|||
return super.getCreatedTime(); |
|||
} |
|||
|
|||
public AlarmComment() { |
|||
super(); |
|||
} |
|||
|
|||
public AlarmComment(AlarmCommentId id) { |
|||
super(id); |
|||
} |
|||
|
|||
@Override |
|||
public String getName() { |
|||
return comment.toString(); |
|||
} |
|||
|
|||
public AlarmComment(AlarmComment alarmComment) { |
|||
super(alarmComment.getId()); |
|||
this.createdTime = alarmComment.getCreatedTime(); |
|||
this.tenantId = alarmComment.getTenantId(); |
|||
this.customerId = alarmComment.getCustomerId(); |
|||
this.type = alarmComment.getType(); |
|||
this.comment = alarmComment.getComment(); |
|||
this.userId = alarmComment.getUserId(); |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
/** |
|||
* 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.common.data.alarm; |
|||
|
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
|
|||
@ApiModel |
|||
public class AlarmCommentInfo extends AlarmComment{ |
|||
private static final long serialVersionUID = 2807343093519543377L; |
|||
|
|||
@ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat") |
|||
private String userName; |
|||
|
|||
public AlarmCommentInfo() { |
|||
super(); |
|||
} |
|||
|
|||
public AlarmCommentInfo(AlarmComment alarmComment) { |
|||
super(alarmComment); |
|||
} |
|||
|
|||
public AlarmCommentInfo(AlarmComment alarmComment, String userName) { |
|||
super(alarmComment); |
|||
this.userName = userName; |
|||
} |
|||
|
|||
public String getUserName() { |
|||
return userName; |
|||
} |
|||
|
|||
public void setOriginatorName(String originatorName) { |
|||
this.userName = originatorName; |
|||
} |
|||
|
|||
@Override |
|||
public boolean equals(Object o) { |
|||
if (this == o) return true; |
|||
if (o == null || getClass() != o.getClass()) return false; |
|||
if (!super.equals(o)) return false; |
|||
|
|||
AlarmCommentInfo alarmCommentInfo = (AlarmCommentInfo) o; |
|||
|
|||
return userName != null ? userName.equals(alarmCommentInfo.userName) : alarmCommentInfo.userName == null; |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public int hashCode() { |
|||
int result = super.hashCode(); |
|||
result = 31 * result + (userName != null ? userName.hashCode() : 0); |
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
/** |
|||
* 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.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
@ApiModel |
|||
public class AlarmCommentId extends UUIDBased implements EntityId{ |
|||
|
|||
private static final long serialVersionUID = 2L; |
|||
|
|||
@JsonCreator |
|||
public AlarmCommentId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static AlarmCommentId fromString(String commentId) { |
|||
return new AlarmCommentId(UUID.fromString(commentId)); |
|||
} |
|||
|
|||
@ApiModelProperty(position = 2, required = true, value = "string", example = "ALARM_COMMENT", allowableValues = "ALARM_COMMENT") |
|||
@Override |
|||
public EntityType getEntityType() { |
|||
return EntityType.ALARM_COMMENT; |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
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.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.Dao; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public interface AlarmCommentDao extends Dao<AlarmComment> { |
|||
AlarmComment createAlarmComment(AlarmComment alarmComment); |
|||
void deleteAlarmComment(AlarmCommentId alarmCommentId); |
|||
|
|||
AlarmComment findAlarmCommentById(TenantId tenantId, UUID key); |
|||
|
|||
PageData<AlarmComment> findAlarmComments(AlarmId id, PageLink pageLink); |
|||
|
|||
ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, UUID key); |
|||
|
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
/** |
|||
* 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.alarm; |
|||
|
|||
import com.google.common.util.concurrent.Futures; |
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
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.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.entity.AbstractEntityService; |
|||
import org.thingsboard.server.dao.entity.EntityService; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
|
|||
import static org.thingsboard.server.dao.service.Validator.validateId; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class BaseAlarmCommentService extends AbstractEntityService implements AlarmCommentService{ |
|||
|
|||
@Autowired |
|||
private AlarmCommentDao alarmCommentDao; |
|||
@Autowired |
|||
private EntityService entityService; |
|||
@Autowired |
|||
private DataValidator<AlarmComment> alarmCommentDataValidator; |
|||
@Override |
|||
public AlarmCommentOperationResult createOrUpdateAlarmComment(AlarmComment alarmComment) { |
|||
alarmCommentDataValidator.validate(alarmComment, AlarmComment::getTenantId); |
|||
alarmComment.setCustomerId(entityService.fetchEntityCustomerId(alarmComment.getTenantId(), alarmComment.getAlarmId())); |
|||
if (alarmComment.getId() == null) { |
|||
return createAlarmComment(alarmComment); |
|||
} else { |
|||
return updateAlarmComment(alarmComment); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
@Transactional |
|||
public AlarmCommentOperationResult deleteAlarmComment(AlarmCommentId alarmCommentId) { |
|||
log.debug("Deleting Alarm Comment with id: {}", alarmCommentId); |
|||
AlarmCommentOperationResult result = new AlarmCommentOperationResult(new AlarmComment(), true); |
|||
alarmCommentDao.deleteAlarmComment(alarmCommentId); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public ListenableFuture<PageData<AlarmComment>> findAlarmComments(AlarmId alarmId, PageLink pageLink) { |
|||
PageData<AlarmComment> alarmComments = alarmCommentDao.findAlarmComments(alarmId, pageLink); |
|||
return Futures.immediateFuture(alarmComments); |
|||
} |
|||
|
|||
@Override |
|||
public ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, AlarmCommentId alarmCommentId) { |
|||
log.trace("Executing findAlarmCommentByIdAsync [{}]", alarmCommentId); |
|||
validateId(alarmCommentId, "Incorrect alarmId " + alarmCommentId); |
|||
return alarmCommentDao.findAlarmCommentByIdAsync(tenantId, alarmCommentId.getId()); |
|||
} |
|||
|
|||
private AlarmCommentOperationResult createAlarmComment(AlarmComment alarmComment) { |
|||
log.debug("New Alarm comment : {}", alarmComment); |
|||
if (alarmComment.getType() == null) { |
|||
alarmComment.setType("OTHER"); |
|||
} |
|||
AlarmComment saved = alarmCommentDao.createAlarmComment(alarmComment); |
|||
return new AlarmCommentOperationResult(saved, true, true); |
|||
} |
|||
|
|||
private AlarmCommentOperationResult updateAlarmComment(AlarmComment newAlarmComment) { |
|||
log.debug("Update Alarm comment : {}", newAlarmComment); |
|||
|
|||
validateId(newAlarmComment.getId(), "Alarm comment id should be specified!"); |
|||
AlarmComment existing = alarmCommentDao.findAlarmCommentById(newAlarmComment.getTenantId(), newAlarmComment.getId().getId()); |
|||
if (existing != null) { |
|||
AlarmComment result = alarmCommentDao.save(newAlarmComment.getTenantId(), merge(existing, newAlarmComment)); |
|||
return new AlarmCommentOperationResult(result, true, true); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private AlarmComment merge(AlarmComment existing, AlarmComment alarmComment) { |
|||
existing.setCustomerId(alarmComment.getCustomerId()); |
|||
existing.setComment(alarmComment.getComment()); |
|||
return existing; |
|||
} |
|||
} |
|||
@ -0,0 +1,119 @@ |
|||
/** |
|||
* 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.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 javax.persistence.Column; |
|||
import javax.persistence.Entity; |
|||
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_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 |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@TypeDef(name = "json", typeClass = JsonStringType.class) |
|||
@Table(name = ALARM_COMMENT_COLUMN_FAMILY_NAME) |
|||
|
|||
public class AlarmCommentEntity extends BaseSqlEntity<AlarmComment> implements BaseEntity<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() { |
|||
super(); |
|||
} |
|||
|
|||
public AlarmCommentEntity(AlarmComment alarmComment) { |
|||
if (alarmComment.getId() != null) { |
|||
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 |
|||
public AlarmComment toData() { |
|||
AlarmComment alarmComment = new AlarmComment(new AlarmCommentId(id)); |
|||
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; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
/** |
|||
* 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.service.validator; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
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.id.TenantId; |
|||
import org.thingsboard.server.dao.exception.DataValidationException; |
|||
import org.thingsboard.server.dao.service.DataValidator; |
|||
import org.thingsboard.server.dao.tenant.TenantService; |
|||
|
|||
@Component |
|||
@AllArgsConstructor |
|||
public class AlarmCommentDataValidator extends DataValidator<AlarmComment> { |
|||
|
|||
private final TenantService tenantService; |
|||
|
|||
@Override |
|||
protected void validateDataImpl(TenantId tenantId, AlarmComment alarmComment) { |
|||
if (alarmComment.getTenantId() == null) { |
|||
throw new DataValidationException("Alarm comment should be assigned to tenant!"); |
|||
} else { |
|||
if (!tenantService.tenantExists(alarmComment.getTenantId())) { |
|||
throw new DataValidationException("Alarm comment is referencing to non-existent tenant!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* 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.sql.alarm; |
|||
|
|||
import org.springframework.data.domain.Page; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.thingsboard.server.dao.model.sql.AlarmCommentEntity; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public interface AlarmCommentRepository extends JpaRepository<AlarmCommentEntity, UUID> { |
|||
|
|||
Page<AlarmCommentEntity> findAllByAlarmId(UUID alarmId, Pageable pageable); |
|||
|
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
/** |
|||
* 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.sql.alarm; |
|||
|
|||
import com.datastax.oss.driver.api.core.uuid.Uuids; |
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.stereotype.Component; |
|||
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.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.alarm.AlarmCommentDao; |
|||
import org.thingsboard.server.dao.model.sql.AlarmCommentEntity; |
|||
import org.thingsboard.server.dao.sql.JpaAbstractDao; |
|||
import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; |
|||
import org.thingsboard.server.dao.util.SqlDao; |
|||
|
|||
import java.util.UUID; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_COLUMN_FAMILY_NAME; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
@SqlDao |
|||
@RequiredArgsConstructor |
|||
public class JpaAlarmCommentDao extends JpaAbstractDao<AlarmCommentEntity, AlarmComment> implements AlarmCommentDao { |
|||
private final SqlPartitioningRepository partitioningRepository; |
|||
@Value("${sql.alarm_comments.partition_size:168}") |
|||
private int partitionSizeInHours; |
|||
|
|||
@Autowired |
|||
private AlarmCommentRepository alarmCommentRepository; |
|||
|
|||
@Override |
|||
public AlarmComment createAlarmComment(AlarmComment 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)); |
|||
AlarmCommentEntity saved = alarmCommentRepository.save(new AlarmCommentEntity(alarmComment)); |
|||
return DaoUtil.getData(saved); |
|||
} |
|||
|
|||
@Override |
|||
public void deleteAlarmComment(AlarmCommentId alarmCommentId){ |
|||
log.trace("Try to delete entity alarm comment by id using [{}]", alarmCommentId); |
|||
alarmCommentRepository.deleteById(alarmCommentId.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public PageData<AlarmComment> findAlarmComments(AlarmId id, PageLink pageLink){ |
|||
log.trace("Try to find alarm comments by alard id using [{}]", id); |
|||
return DaoUtil.toPageData( |
|||
alarmCommentRepository.findAllByAlarmId(id.getId(), DaoUtil.toPageable(pageLink))); |
|||
} |
|||
|
|||
@Override |
|||
public AlarmComment findAlarmCommentById(TenantId tenantId, UUID key) { |
|||
return findById(tenantId, key); |
|||
} |
|||
|
|||
@Override |
|||
public ListenableFuture<AlarmComment> findAlarmCommentByIdAsync(TenantId tenantId, UUID key) { |
|||
return findByIdAsync(tenantId, key); |
|||
} |
|||
|
|||
@Override |
|||
protected Class<AlarmCommentEntity> getEntityClass() { |
|||
return AlarmCommentEntity.class; |
|||
} |
|||
|
|||
@Override |
|||
protected JpaRepository<AlarmCommentEntity, UUID> getRepository() { |
|||
return alarmCommentRepository; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue