committed by
GitHub
31 changed files with 987 additions and 384 deletions
@ -0,0 +1,95 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 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.event; |
||||
|
|
||||
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
|
import lombok.Builder; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
import lombok.ToString; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.EventInfo; |
||||
|
import org.thingsboard.server.common.data.id.CalculatedFieldId; |
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
@ToString |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
public class CalculatedFieldDebugEvent extends Event { |
||||
|
|
||||
|
private static final long serialVersionUID = -7091690784759639853L; |
||||
|
|
||||
|
@Builder |
||||
|
private CalculatedFieldDebugEvent(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts, |
||||
|
CalculatedFieldId calculatedFieldId, EntityId eventEntity, UUID msgId, |
||||
|
String msgType, String arguments, String result, String error) { |
||||
|
super(tenantId, entityId, serviceId, id, ts); |
||||
|
this.calculatedFieldId = calculatedFieldId; |
||||
|
this.eventEntity = eventEntity; |
||||
|
this.msgId = msgId; |
||||
|
this.msgType = msgType; |
||||
|
this.arguments = arguments; |
||||
|
this.result = result; |
||||
|
this.error = error; |
||||
|
} |
||||
|
|
||||
|
@Getter |
||||
|
private final CalculatedFieldId calculatedFieldId; |
||||
|
@Getter |
||||
|
private final EntityId eventEntity; |
||||
|
@Getter |
||||
|
private final UUID msgId; |
||||
|
@Getter |
||||
|
private final String msgType; |
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String arguments; |
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String result; |
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String error; |
||||
|
|
||||
|
@Override |
||||
|
public EventType getType() { |
||||
|
return EventType.DEBUG_CALCULATED_FIELD; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public EventInfo toInfo(EntityType entityType) { |
||||
|
EventInfo eventInfo = super.toInfo(entityType); |
||||
|
var json = (ObjectNode) eventInfo.getBody(); |
||||
|
json.put("calculatedFieldId", calculatedFieldId.toString()); |
||||
|
if (eventEntity != null) { |
||||
|
json.put("entityId", eventEntity.getId().toString()) |
||||
|
.put("entityType", eventEntity.getEntityType().name()); |
||||
|
} |
||||
|
if (msgId != null) { |
||||
|
json.put("msgId", msgId.toString()); |
||||
|
} |
||||
|
putNotNull(json, "msgType", msgType); |
||||
|
putNotNull(json, "arguments", arguments); |
||||
|
putNotNull(json, "result", result); |
||||
|
putNotNull(json, "error", error); |
||||
|
return eventInfo; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 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.event; |
||||
|
|
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import org.thingsboard.server.common.data.StringUtils; |
||||
|
|
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@Schema |
||||
|
public class CalculatedFieldDebugEventFilter extends DebugEventFilter { |
||||
|
|
||||
|
@Schema(description = "String value representing the calculated field id in the event body", example = "ccbfa2fe-c8f5-45d8-bb37-6b61a6e02833") |
||||
|
protected String calculatedFieldId; |
||||
|
@Schema(description = "String value representing the entity id in the event body", example = "57b6bafe-d600-423c-9267-fe31e5218986") |
||||
|
protected String entityId; |
||||
|
@Schema(description = "String value representing the entity type", allowableValues = "DEVICE") |
||||
|
protected String entityType; |
||||
|
@Schema(description = "String value representing the message id in the rule engine", example = "dcf44612-2ce4-4e5d-b462-ebb9c5628228") |
||||
|
protected String msgId; |
||||
|
@Schema(description = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") |
||||
|
protected String msgType; |
||||
|
|
||||
|
@Override |
||||
|
public EventType getEventType() { |
||||
|
return EventType.DEBUG_CALCULATED_FIELD; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isNotEmpty() { |
||||
|
return super.isNotEmpty() || !StringUtils.isEmpty(calculatedFieldId) || !StringUtils.isEmpty(entityId) |
||||
|
|| !StringUtils.isEmpty(entityType) || !StringUtils.isEmpty(msgId) || !StringUtils.isEmpty(msgType); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,104 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 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 jakarta.persistence.Column; |
||||
|
import jakarta.persistence.Entity; |
||||
|
import jakarta.persistence.Table; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import org.thingsboard.server.common.data.event.CalculatedFieldDebugEvent; |
||||
|
import org.thingsboard.server.common.data.id.CalculatedFieldId; |
||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.dao.model.BaseEntity; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.CALCULATED_FIELD_DEBUG_EVENT_TABLE_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_CALCULATED_FIELD_ARGUMENTS_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_CALCULATED_FIELD_ID_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_CALCULATED_FIELD_RESULT_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_ID_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_TYPE_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MSG_ID_COLUMN_NAME; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MSG_TYPE_COLUMN_NAME; |
||||
|
|
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@Entity |
||||
|
@Table(name = CALCULATED_FIELD_DEBUG_EVENT_TABLE_NAME) |
||||
|
@NoArgsConstructor |
||||
|
public class CalculatedFieldDebugEventEntity extends EventEntity<CalculatedFieldDebugEvent> implements BaseEntity<CalculatedFieldDebugEvent> { |
||||
|
|
||||
|
@Column(name = EVENT_CALCULATED_FIELD_ID_COLUMN_NAME) |
||||
|
private UUID calculatedFieldId; |
||||
|
@Column(name = EVENT_ENTITY_ID_COLUMN_NAME) |
||||
|
private UUID eventEntityId; |
||||
|
@Column(name = EVENT_ENTITY_TYPE_COLUMN_NAME) |
||||
|
private String eventEntityType; |
||||
|
@Column(name = EVENT_MSG_ID_COLUMN_NAME) |
||||
|
private UUID msgId; |
||||
|
@Column(name = EVENT_MSG_TYPE_COLUMN_NAME) |
||||
|
private String msgType; |
||||
|
@Column(name = EVENT_CALCULATED_FIELD_ARGUMENTS_COLUMN_NAME) |
||||
|
private String arguments; |
||||
|
@Column(name = EVENT_CALCULATED_FIELD_RESULT_COLUMN_NAME) |
||||
|
private String result; |
||||
|
@Column(name = EVENT_ERROR_COLUMN_NAME) |
||||
|
private String error; |
||||
|
|
||||
|
public CalculatedFieldDebugEventEntity(CalculatedFieldDebugEvent event) { |
||||
|
super(event); |
||||
|
if (event.getCalculatedFieldId() != null) { |
||||
|
this.calculatedFieldId = event.getCalculatedFieldId().getId(); |
||||
|
} |
||||
|
if (event.getEventEntity() != null) { |
||||
|
this.eventEntityId = event.getEventEntity().getId(); |
||||
|
this.eventEntityType = event.getEventEntity().getEntityType().name(); |
||||
|
} |
||||
|
this.msgId = event.getMsgId(); |
||||
|
this.msgType = event.getMsgType(); |
||||
|
this.arguments = event.getArguments(); |
||||
|
this.result = event.getResult(); |
||||
|
this.error = event.getError(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public CalculatedFieldDebugEvent toData() { |
||||
|
var builder = CalculatedFieldDebugEvent.builder() |
||||
|
.id(id) |
||||
|
.tenantId(TenantId.fromUUID(tenantId)) |
||||
|
.ts(ts) |
||||
|
.serviceId(serviceId) |
||||
|
.entityId(entityId) |
||||
|
.msgId(msgId) |
||||
|
.msgType(msgType) |
||||
|
.arguments(arguments) |
||||
|
.result(result) |
||||
|
.error(error); |
||||
|
if (calculatedFieldId != null) { |
||||
|
builder.calculatedFieldId(new CalculatedFieldId(calculatedFieldId)); |
||||
|
} |
||||
|
if (eventEntityId != null) { |
||||
|
builder.eventEntity(EntityIdFactory.getByTypeAndUuid(eventEntityType, eventEntityId)); |
||||
|
} |
||||
|
return builder.build(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,135 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2024 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.event; |
||||
|
|
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.data.jpa.repository.JpaRepository; |
||||
|
import org.springframework.data.jpa.repository.Modifying; |
||||
|
import org.springframework.data.jpa.repository.Query; |
||||
|
import org.springframework.data.repository.query.Param; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.thingsboard.server.common.data.event.CalculatedFieldDebugEvent; |
||||
|
import org.thingsboard.server.dao.model.sql.CalculatedFieldDebugEventEntity; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
public interface CalculatedFieldDebugEventRepository extends EventRepository<CalculatedFieldDebugEventEntity, CalculatedFieldDebugEvent>, JpaRepository<CalculatedFieldDebugEventEntity, UUID> { |
||||
|
|
||||
|
@Override |
||||
|
@Query(nativeQuery = true, value = "SELECT * FROM cf_debug_event e WHERE e.tenant_id = :tenantId AND e.entity_id = :entityId ORDER BY e.ts DESC LIMIT :limit") |
||||
|
List<CalculatedFieldDebugEventEntity> findLatestEvents(@Param("tenantId") UUID tenantId, @Param("entityId") UUID entityId, @Param("limit") int limit); |
||||
|
|
||||
|
@Override |
||||
|
@Query("SELECT e FROM RuleNodeDebugEventEntity e WHERE " + |
||||
|
"e.tenantId = :tenantId " + |
||||
|
"AND e.entityId = :entityId " + |
||||
|
"AND (:startTime IS NULL OR e.ts >= :startTime) " + |
||||
|
"AND (:endTime IS NULL OR e.ts <= :endTime)" |
||||
|
) |
||||
|
Page<CalculatedFieldDebugEventEntity> findEvents(@Param("tenantId") UUID tenantId, |
||||
|
@Param("entityId") UUID entityId, |
||||
|
@Param("startTime") Long startTime, |
||||
|
@Param("endTime") Long endTime, |
||||
|
Pageable pageable); |
||||
|
|
||||
|
@Query(nativeQuery = true, |
||||
|
value = "SELECT * FROM cf_debug_event e WHERE " + |
||||
|
"e.tenant_id = :tenantId " + |
||||
|
"AND e.entity_id = :entityId " + |
||||
|
"AND (:startTime IS NULL OR e.ts >= :startTime) " + |
||||
|
"AND (:endTime IS NULL OR e.ts <= :endTime) " + |
||||
|
"AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + |
||||
|
"AND (:calculatedFieldId IS NULL OR e.cf_id = uuid(:calculatedFieldId)) " + |
||||
|
"AND (:eventEntityId IS NULL OR e.e_entity_id = uuid(:eventEntityId)) " + |
||||
|
"AND (:eventEntityType IS NULL OR e.e_entity_type ILIKE concat('%', :eventEntityType, '%')) " + |
||||
|
"AND (:msgId IS NULL OR e.e_msg_id = uuid(:msgId)) " + |
||||
|
"AND (:msgType IS NULL OR e.e_msg_type ILIKE concat('%', :msgType, '%')) " + |
||||
|
"AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + |
||||
|
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" |
||||
|
, |
||||
|
countQuery = "SELECT count(*) FROM rule_node_debug_event e WHERE " + |
||||
|
"e.tenant_id = :tenantId " + |
||||
|
"AND e.entity_id = :entityId " + |
||||
|
"AND (:startTime IS NULL OR e.ts >= :startTime) " + |
||||
|
"AND (:endTime IS NULL OR e.ts <= :endTime) " + |
||||
|
"AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + |
||||
|
"AND (:calculatedFieldId IS NULL OR e.cf_id = uuid(:calculatedFieldId)) " + |
||||
|
"AND (:eventEntityId IS NULL OR e.e_entity_id = uuid(:eventEntityId)) " + |
||||
|
"AND (:eventEntityType IS NULL OR e.e_entity_type ILIKE concat('%', :eventEntityType, '%')) " + |
||||
|
"AND (:msgId IS NULL OR e.e_msg_id = uuid(:msgId)) " + |
||||
|
"AND (:msgType IS NULL OR e.e_msg_type ILIKE concat('%', :msgType, '%')) " + |
||||
|
"AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + |
||||
|
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))" |
||||
|
) |
||||
|
Page<CalculatedFieldDebugEventEntity> findEvents(@Param("tenantId") UUID tenantId, |
||||
|
@Param("entityId") UUID entityId, |
||||
|
@Param("startTime") Long startTime, |
||||
|
@Param("endTime") Long endTime, |
||||
|
@Param("serviceId") String server, |
||||
|
@Param("calculatedFieldId") UUID calculatedFieldId, |
||||
|
@Param("eventEntityId") String eventEntityId, |
||||
|
@Param("eventEntityType") String eventEntityType, |
||||
|
@Param("msgId") String eventMsgId, |
||||
|
@Param("msgType") String eventMsgType, |
||||
|
@Param("isError") boolean isError, |
||||
|
@Param("error") String error, |
||||
|
Pageable pageable); |
||||
|
|
||||
|
@Transactional |
||||
|
@Modifying |
||||
|
@Query("DELETE FROM CalculatedFieldDebugEventEntity e WHERE " + |
||||
|
"e.tenantId = :tenantId " + |
||||
|
"AND e.entityId = :entityId " + |
||||
|
"AND (:startTime IS NULL OR e.ts >= :startTime) " + |
||||
|
"AND (:endTime IS NULL OR e.ts <= :endTime)" |
||||
|
) |
||||
|
void removeEvents(@Param("tenantId") UUID tenantId, |
||||
|
@Param("entityId") UUID entityId, |
||||
|
@Param("startTime") Long startTime, |
||||
|
@Param("endTime") Long endTime); |
||||
|
|
||||
|
@Transactional |
||||
|
@Modifying |
||||
|
@Query(nativeQuery = true, |
||||
|
value = "DELETE FROM cf_debug_event e WHERE " + |
||||
|
"e.tenant_id = :tenantId " + |
||||
|
"AND e.entity_id = :entityId " + |
||||
|
"AND (:startTime IS NULL OR e.ts >= :startTime) " + |
||||
|
"AND (:endTime IS NULL OR e.ts <= :endTime) " + |
||||
|
"AND (:serviceId IS NULL OR e.service_id ILIKE concat('%', :serviceId, '%')) " + |
||||
|
"AND (:calculatedFieldId IS NULL OR e.cf_id = uuid(:calculatedFieldId)) " + |
||||
|
"AND (:eventEntityId IS NULL OR e.e_entity_id = uuid(:eventEntityId)) " + |
||||
|
"AND (:eventEntityType IS NULL OR e.e_entity_type ILIKE concat('%', :eventEntityType, '%')) " + |
||||
|
"AND (:msgId IS NULL OR e.e_msg_id = uuid(:msgId)) " + |
||||
|
"AND (:msgType IS NULL OR e.e_msg_type ILIKE concat('%', :msgType, '%')) " + |
||||
|
"AND ((:isError = FALSE) OR e.e_error IS NOT NULL) " + |
||||
|
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))") |
||||
|
void removeEvents(@Param("tenantId") UUID tenantId, |
||||
|
@Param("entityId") UUID entityId, |
||||
|
@Param("startTime") Long startTime, |
||||
|
@Param("endTime") Long endTime, |
||||
|
@Param("serviceId") String server, |
||||
|
@Param("calculatedFieldId") UUID calculatedFieldId, |
||||
|
@Param("eventEntityId") String eventEntityId, |
||||
|
@Param("eventEntityType") String eventEntityType, |
||||
|
@Param("msgId") String eventMsgId, |
||||
|
@Param("msgType") String eventMsgType, |
||||
|
@Param("isError") boolean isError, |
||||
|
@Param("error") String error); |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue