Browse Source

WIP: improvement to fetch of the events

pull/7001/head
Andrii Shvaika 4 years ago
parent
commit
e89554aaf4
  1. 10
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 2
      application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java
  3. 2
      application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
  4. 62
      application/src/main/java/org/thingsboard/server/controller/EventController.java
  5. 3
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  6. 4
      application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java
  7. 3
      application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java
  8. 9
      common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java
  9. 6
      common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
  10. 13
      common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java
  11. 31
      common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java
  12. 7
      common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java
  13. 29
      common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java
  14. 11
      common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java
  15. 11
      common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java
  16. 13
      common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java
  17. 70
      dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java
  18. 20
      dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java
  19. 21
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  20. 73
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java
  21. 114
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
  22. 72
      dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java
  23. 72
      dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java
  24. 74
      dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java
  25. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java
  26. 384
      dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java
  27. 148
      dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
  28. 76
      dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java
  29. 46
      dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java
  30. 24
      dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql
  31. 12
      dao/src/main/resources/sql/schema-entities.sql
  32. 2
      dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
  33. 11
      dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java
  34. 20
      dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java

10
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -488,7 +488,7 @@ public class ActorSystemContext {
public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) {
eventService.saveAsync(ErrorEvent.builder()
.tenantId(tenantId)
.entityId(entityId)
.entityId(entityId.getId())
.serviceId(getServiceId())
.method(method)
.error(toString(e)).build());
@ -497,14 +497,14 @@ public class ActorSystemContext {
public void persistLifecycleEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent lcEvent, Exception e) {
LifecycleEvent.LifecycleEventBuilder event = LifecycleEvent.builder()
.tenantId(tenantId)
.entityId(entityId)
.entityId(entityId.getId())
.serviceId(getServiceId())
.lcEventType(lcEvent.name());
if (e != null) {
event.success(false).error(toString(e));
} else {
event.success(false);
event.success(true);
}
eventService.saveAsync(event.build());
@ -553,7 +553,7 @@ public class ActorSystemContext {
try {
RuleNodeDebugEvent.RuleNodeDebugEventBuilder event = RuleNodeDebugEvent.builder()
.tenantId(tenantId)
.entityId(entityId)
.entityId(entityId.getId())
.serviceId(getServiceId())
.eventType(type)
.eventEntity(tbMsg.getOriginator())
@ -600,7 +600,7 @@ public class ActorSystemContext {
private void persistRuleChainDebugModeEvent(TenantId tenantId, EntityId entityId, Throwable error) {
RuleChainDebugEvent.RuleChainDebugEventBuilder event = RuleChainDebugEvent.builder()
.tenantId(tenantId)
.entityId(entityId)
.entityId(entityId.getId())
.serviceId(getServiceId())
.message("Reached debug mode rate limit!");
if (error != null) {

2
application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java

@ -56,7 +56,7 @@ public class StatsActor extends ContextAwareActor {
}
systemContext.getEventService().saveAsync(StatisticsEvent.builder()
.tenantId(msg.getTenantId())
.entityId(msg.getEntityId())
.entityId(msg.getEntityId().getId())
.serviceId(systemContext.getServiceInfoProvider().getServiceId())
.messagesProcessed(msg.getMessagesProcessed())
.errorsOccurred(msg.getErrorsOccurred())

2
application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java

@ -94,7 +94,7 @@ public class ControllerConstants {
protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault";
protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status";
protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id";
protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "ts, id";
protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root";
protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId";

62
application/src/main/java/org/thingsboard/server/controller/EventController.java

@ -29,8 +29,11 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.EventFilter;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
@ -42,6 +45,8 @@ import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
import java.util.Locale;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE;
@ -135,16 +140,12 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
try {
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(eventService.findEvents(tenantId, entityId, eventType, pageLink));
} catch (Exception e) {
throw handleException(e);
}
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(eventService.findEvents(tenantId, entityId, resolveEventType(eventType), pageLink));
}
@ApiOperation(value = "Get Events (getEvents)",
@ -176,18 +177,14 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
try {
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(eventService.findEvents(tenantId, entityId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
return checkNotNull(eventService.findEvents(tenantId, entityId, EventType.LC_EVENT, pageLink));
}
@ApiOperation(value = "Get Events by event filter (getEvents)",
@ -223,21 +220,17 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
try {
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
if (sortProperty != null && sortProperty.equals("createdTime") && eventFilter.hasFilterForJsonBody()) {
sortProperty = ModelConstants.CREATED_TIME_PROPERTY;
}
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
checkEntityId(entityId, Operation.READ);
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(eventService.findEventsByFilter(tenantId, entityId, eventFilter, pageLink));
} catch (Exception e) {
throw handleException(e);
if (sortProperty != null && sortProperty.equals("createdTime")) {
sortProperty = ModelConstants.TS_COLUMN;
}
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
return checkNotNull(eventService.findEventsByFilter(tenantId, entityId, eventFilter, pageLink));
}
@ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events by filter for specified entity.")
@ -266,4 +259,13 @@ public class EventController extends BaseController {
}
}
private static EventType resolveEventType(String eventType) throws ThingsboardException {
for (var et : EventType.values()) {
if (et.name().equalsIgnoreCase(eventType) || et.getOldName().equalsIgnoreCase(eventType)) {
return et;
}
}
throw new ThingsboardException("Event type: '" + eventType + "' is not supported!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
}
}

3
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
@ -352,7 +353,7 @@ public class RuleChainController extends BaseController {
RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId));
checkRuleNode(ruleNodeId, Operation.READ);
TenantId tenantId = getCurrentUser().getTenantId();
List<EventInfo> events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2);
List<EventInfo> events = eventService.findLatestEvents(tenantId, ruleNodeId, EventType.DEBUG_RULE_NODE, 2);
JsonNode result = null;
if (events != null) {
for (EventInfo event : events) {

4
application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
@ -61,7 +62,7 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle
}
protected PageData<EventInfo> getDebugEvents(TenantId tenantId, EntityId entityId, int limit) throws Exception {
return getEvents(tenantId, entityId, DataConstants.DEBUG_RULE_NODE, limit);
return getEvents(tenantId, entityId, EventType.DEBUG_RULE_NODE.getOldName(), limit);
}
protected PageData<EventInfo> getEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) throws Exception {
@ -72,7 +73,6 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle
}
protected JsonNode getMetadata(EventInfo outEvent) {
String metaDataStr = outEvent.getBody().get("metadata").asText();
try {

3
application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java

@ -28,6 +28,7 @@ import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.rule.RuleChain;
@ -109,7 +110,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
.pollInterval(10, MILLISECONDS)
.atMost(TIMEOUT, TimeUnit.SECONDS)
.until(() -> {
List<EventInfo> debugEvents = getEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), DataConstants.LC_EVENT, 1000)
List<EventInfo> debugEvents = getEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), EventType.LC_EVENT.getOldName(), 1000)
.getData().stream().filter(e -> {
var body = e.getBody();
return body.has("event") && body.get("event").asText().equals("STARTED")

9
common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java

@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.event.EventFilter;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -31,13 +32,9 @@ public interface EventService {
ListenableFuture<Void> saveAsync(Event event);
Optional<EventInfo> findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid);
PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, EventType eventType, TimePageLink pageLink);
PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink);
PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink);
List<EventInfo> findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit);
List<EventInfo> findLatestEvents(TenantId tenantId, EntityId entityId, EventType eventType, int limit);
PageData<EventInfo> findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink);

6
common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java

@ -52,12 +52,6 @@ public class DataConstants {
}
public static final String ALARM = "ALARM";
public static final String ERROR = "ERROR";
public static final String LC_EVENT = "LC_EVENT";
public static final String STATS = "STATS";
public static final String DEBUG_RULE_NODE = "DEBUG_RULE_NODE";
public static final String DEBUG_RULE_CHAIN = "DEBUG_RULE_CHAIN";
public static final String IN = "IN";
public static final String OUT = "OUT";

13
common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java

@ -20,9 +20,13 @@ 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.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import java.util.UUID;
@ToString
@EqualsAndHashCode(callSuper = true)
public class ErrorEvent extends Event {
@ -30,8 +34,8 @@ public class ErrorEvent extends Event {
private static final long serialVersionUID = 960461434033192571L;
@Builder
private ErrorEvent(TenantId tenantId, EntityId entityId, String serviceId, String method, String error) {
super(tenantId, entityId, serviceId);
private ErrorEvent(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts, String method, String error) {
super(tenantId, entityId, serviceId, id, ts);
this.method = method;
this.error = error;
}
@ -45,4 +49,9 @@ public class ErrorEvent extends Event {
public EventType getType() {
return EventType.ERROR;
}
@Override
public EventInfo toInfo(EntityType entityType) {
return null;
}
}

31
common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java

@ -15,28 +15,49 @@
*/
package org.thingsboard.server.common.data.event;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EventId;
import org.thingsboard.server.common.data.id.TenantId;
import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class Event extends BaseData<EventId> {
private final TenantId tenantId;
private final EntityId entityId;
private final String serviceId;
protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
protected final TenantId tenantId;
protected final UUID entityId;
protected final String serviceId;
public Event(TenantId tenantId, EntityId entityId, String serviceId) {
public Event(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts) {
super();
if (id != null) {
this.id = new EventId(id);
}
this.tenantId = tenantId != null ? tenantId : TenantId.SYS_TENANT_ID;
this.entityId = entityId;
this.serviceId = serviceId;
this.createdTime = ts;
}
public abstract EventType getType();
public EventInfo toInfo(EntityType entityType) {
EventInfo eventInfo = new EventInfo();
eventInfo.setTenantId(tenantId);
eventInfo.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
eventInfo.setType(getType().getOldName());
eventInfo.setId(id);
eventInfo.setCreatedTime(createdTime);
eventInfo.setBody(OBJECT_MAPPER.createObjectNode().put("server", getServiceId()));
return eventInfo;
}
}

7
common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java

@ -18,13 +18,16 @@ package org.thingsboard.server.common.data.event;
import lombok.Getter;
public enum EventType {
ERROR("error_event"), LC_EVENT("lc_event"), STATS("stats_event"), DEBUG_RULE_NODE("rule_node_debug_event"), DEBUG_RULE_CHAIN("rule_chain_debug_event");
ERROR("error_event", "ERROR"), LC_EVENT("lc_event", "LC_EVENT"), STATS("stats_event", "STATS"), DEBUG_RULE_NODE("rule_node_debug_event", "DEBUG_RULE_NODE"), DEBUG_RULE_CHAIN("rule_chain_debug_event", "DEBUG_RULE_CHAIN");
@Getter
private final String table;
@Getter
private final String oldName;
EventType(String table) {
EventType(String table, String oldName) {
this.table = table;
this.oldName = oldName;
}
}

29
common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java

@ -15,14 +15,21 @@
*/
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.jetbrains.annotations.NotNull;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import java.util.UUID;
@ToString
@EqualsAndHashCode(callSuper = true)
public class LifecycleEvent extends Event {
@ -30,8 +37,10 @@ public class LifecycleEvent extends Event {
private static final long serialVersionUID = -3247420461850911549L;
@Builder
private LifecycleEvent(TenantId tenantId, EntityId entityId, String serviceId, String lcEventType, boolean success, String error) {
super(tenantId, entityId, serviceId);
private LifecycleEvent(TenantId tenantId, UUID entityId, String serviceId,
UUID id, long ts,
String lcEventType, boolean success, String error) {
super(tenantId, entityId, serviceId, id, ts);
this.lcEventType = lcEventType;
this.success = success;
this.error = error;
@ -41,11 +50,25 @@ public class LifecycleEvent extends Event {
private final String lcEventType;
@Getter
private final boolean success;
@Getter @Setter
@Getter
@Setter
private String error;
@Override
public EventType getType() {
return EventType.LC_EVENT;
}
@Override
public EventInfo toInfo(EntityType entityType) {
EventInfo eventInfo = super.toInfo(entityType);
var json = (ObjectNode) eventInfo.getBody();
json.put("event", lcEventType)
.put("success", success);
if (error != null) {
json.put("error", error);
}
return eventInfo;
}
}

11
common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java

@ -20,6 +20,8 @@ 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.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
@ -32,8 +34,8 @@ public class RuleChainDebugEvent extends Event {
private static final long serialVersionUID = -386392236201116767L;
@Builder
private RuleChainDebugEvent(TenantId tenantId, EntityId entityId, String serviceId, String message, String error) {
super(tenantId, entityId, serviceId);
private RuleChainDebugEvent(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts, String message, String error) {
super(tenantId, entityId, serviceId, id, ts);
this.message = message;
this.error = error;
}
@ -47,4 +49,9 @@ public class RuleChainDebugEvent extends Event {
public EventType getType() {
return EventType.DEBUG_RULE_CHAIN;
}
@Override
public EventInfo toInfo(EntityType entityType) {
return null;
}
}

11
common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java

@ -20,6 +20,8 @@ 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.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
@ -32,11 +34,11 @@ public class RuleNodeDebugEvent extends Event {
private static final long serialVersionUID = -6575797430064573984L;
@Builder
private RuleNodeDebugEvent(TenantId tenantId, EntityId entityId, String serviceId,
private RuleNodeDebugEvent(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts,
String eventType, EntityId eventEntity, UUID msgId,
String msgType, String dataType, String relationType,
String data, String metadata, String error) {
super(tenantId, entityId, serviceId);
super(tenantId, entityId, serviceId, id, ts);
this.eventType = eventType;
this.eventEntity = eventEntity;
this.msgId = msgId;
@ -72,4 +74,9 @@ public class RuleNodeDebugEvent extends Event {
public EventType getType() {
return EventType.DEBUG_RULE_NODE;
}
@Override
public EventInfo toInfo(EntityType entityType) {
return null;
}
}

13
common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java

@ -19,9 +19,13 @@ import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
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 StatisticsEvent extends Event {
@ -29,8 +33,8 @@ public class StatisticsEvent extends Event {
private static final long serialVersionUID = 6683733979448910631L;
@Builder
private StatisticsEvent(TenantId tenantId, EntityId entityId, String serviceId, long messagesProcessed, long errorsOccurred) {
super(tenantId, entityId, serviceId);
private StatisticsEvent(TenantId tenantId, UUID entityId, String serviceId, UUID id, long ts, long messagesProcessed, long errorsOccurred) {
super(tenantId, entityId, serviceId, id, ts);
this.messagesProcessed = messagesProcessed;
this.errorsOccurred = errorsOccurred;
}
@ -44,4 +48,9 @@ public class StatisticsEvent extends Event {
public EventType getType() {
return EventType.STATS;
}
@Override
public EventInfo toInfo(EntityType entityType) {
return null;
}
}

70
dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java

@ -20,24 +20,23 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.event.ErrorEvent;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.event.EventFilter;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.event.LifecycleEvent;
import org.thingsboard.server.common.data.event.RuleChainDebugEvent;
import org.thingsboard.server.common.data.event.RuleNodeDebugEvent;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.IdBased;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -97,41 +96,18 @@ public class BaseEventService implements EventService {
}
@Override
public Optional<EventInfo> findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid) {
if (tenantId == null) {
throw new DataValidationException("Tenant id should be specified!.");
}
if (entityId == null) {
throw new DataValidationException("Entity id should be specified!.");
}
if (StringUtils.isEmpty(eventType)) {
throw new DataValidationException("Event type should be specified!.");
}
if (StringUtils.isEmpty(eventUid)) {
throw new DataValidationException("Event uid should be specified!.");
}
EventInfo event = eventDao.findEvent(tenantId.getId(), entityId, eventType, eventUid);
return event != null ? Optional.of(event) : Optional.empty();
}
@Override
public PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) {
return eventDao.findEvents(tenantId.getId(), entityId, pageLink);
public PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, EventType eventType, TimePageLink pageLink) {
return convert(entityId.getEntityType(), eventDao.findEvents(tenantId.getId(), entityId.getId(), eventType, pageLink));
}
@Override
public PageData<EventInfo> findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
return eventDao.findEvents(tenantId.getId(), entityId, eventType, pageLink);
}
@Override
public List<EventInfo> findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) {
return eventDao.findLatestEvents(tenantId.getId(), entityId, eventType, limit);
public List<EventInfo> findLatestEvents(TenantId tenantId, EntityId entityId, EventType eventType, int limit) {
return eventDao.findLatestEvents(tenantId.getId(), entityId.getId(), eventType, limit);
}
@Override
public PageData<EventInfo> findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) {
return eventDao.findEventByFilter(tenantId.getId(), entityId, eventFilter, pageLink);
return convert(entityId.getEntityType(), eventDao.findEventByFilter(tenantId.getId(), entityId.getId(), eventFilter, pageLink));
}
@Override
@ -141,23 +117,29 @@ public class BaseEventService implements EventService {
@Override
public void removeEvents(TenantId tenantId, EntityId entityId, EventFilter eventFilter, Long startTime, Long endTime) {
TimePageLink eventsPageLink = new TimePageLink(1000, 0, null, null, startTime, endTime);
PageData<EventInfo> eventsPageData;
do {
if (eventFilter == null) {
eventsPageData = findEvents(tenantId, entityId, eventsPageLink);
} else {
eventsPageData = findEventsByFilter(tenantId, entityId, eventFilter, eventsPageLink);
}
eventDao.removeAllByIds(eventsPageData.getData().stream()
.map(IdBased::getUuidId)
.collect(Collectors.toList()));
} while (eventsPageData.hasNext());
// TimePageLink eventsPageLink = new TimePageLink(1000, 0, null, null, startTime, endTime);
// PageData<EventInfo> eventsPageData;
// do {
// if (eventFilter == null) {
// eventsPageData = findEvents(tenantId, entityId, eventsPageLink);
// } else {
// eventsPageData = findEventsByFilter(tenantId, entityId, eventFilter, eventsPageLink);
// }
//
// eventDao.removeAllByIds(eventsPageData.getData().stream()
// .map(IdBased::getUuidId)
// .collect(Collectors.toList()));
// } while (eventsPageData.hasNext());
}
@Override
public void cleanupEvents(long regularEventStartTs, long regularEventEndTs, long debugEventStartTs, long debugEventEndTs) {
eventDao.cleanupEvents(regularEventStartTs, regularEventEndTs, debugEventStartTs, debugEventEndTs);
}
private PageData<EventInfo> convert(EntityType entityType, PageData<? extends Event> pd) {
return new PageData<>(pd.getData() == null ? null :
pd.getData().stream().map(e -> e.toInfo(entityType)).collect(Collectors.toList())
, pd.getTotalPages(), pd.getTotalElements(), pd.hasNext());
}
}

20
dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java

@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.event.EventFilter;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink;
@ -30,7 +31,7 @@ import java.util.UUID;
/**
* The Interface EventDao.
*/
public interface EventDao extends Dao<Event> {
public interface EventDao {
/**
* Save or update event object async
@ -40,17 +41,6 @@ public interface EventDao extends Dao<Event> {
*/
ListenableFuture<Void> saveAsync(Event event);
/**
* Find event by tenantId, entityId and eventUid.
*
* @param tenantId the tenantId
* @param entityId the entityId
* @param eventType the eventType
* @param eventUid the eventUid
* @return the event
*/
EventInfo findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid);
/**
* Find events by tenantId, entityId and pageLink.
*
@ -70,9 +60,9 @@ public interface EventDao extends Dao<Event> {
* @param pageLink the pageLink
* @return the event list
*/
PageData<EventInfo> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink);
PageData<? extends Event> findEvents(UUID tenantId, UUID entityId, EventType eventType, TimePageLink pageLink);
PageData<EventInfo> findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink);
PageData<? extends Event> findEventByFilter(UUID tenantId, UUID entityId, EventFilter eventFilter, TimePageLink pageLink);
/**
* Find latest events by tenantId, entityId and eventType.
@ -83,7 +73,7 @@ public interface EventDao extends Dao<Event> {
* @param limit the limit
* @return the event list
*/
List<EventInfo> findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit);
List<EventInfo> findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit);
/**
* Executes stored procedure to cleanup old events. Uses separate ttl for debug and other events.

21
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -368,16 +368,25 @@ public class ModelConstants {
/**
* Cassandra event constants.
*/
public static final String EVENT_COLUMN_FAMILY_NAME = "event";
public static final String ERROR_EVENT_TABLE_NAME = "error_event";
public static final String LC_EVENT_TABLE_NAME = "lc_event";
public static final String STATS_EVENT_TABLE_NAME = "stats_event";
public static final String RULE_NODE_DEBUG_EVENT_TABLE_NAME = "rule_node_debug_event";
public static final String RULE_CHAIN_DEBUG_EVENT_TABLE_NAME = "rule_chain_debug_event";
public static final String EVENT_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
public static final String EVENT_TYPE_PROPERTY = "event_type";
public static final String EVENT_UID_PROPERTY = "event_uid";
public static final String EVENT_ENTITY_TYPE_PROPERTY = ENTITY_TYPE_PROPERTY;
public static final String EVENT_SERVICE_ID_PROPERTY = "service_id";
public static final String EVENT_ENTITY_ID_PROPERTY = "entity_id";
public static final String EVENT_BODY_PROPERTY = "body";
public static final String EVENT_BY_TYPE_AND_ID_VIEW_NAME = "event_by_type_and_id";
public static final String EVENT_BY_ID_VIEW_NAME = "event_by_id";
public static final String EVENT_MESSAGES_PROCESSED_COLUMN_NAME = "e_messages_processed";
public static final String EVENT_ERRORS_OCCURRED_COLUMN_NAME = "e_errors_occurred";
public static final String EVENT_METHOD_COLUMN_NAME = "e_method";
public static final String EVENT_TYPE_COLUMN_NAME = "e_type";
public static final String EVENT_ERROR_COLUMN_NAME = "e_error";
public static final String EVENT_SUCCESS_COLUMN_NAME = "e_success";
public static final String DEBUG_MODE = "debug_mode";

73
dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java

@ -0,0 +1,73 @@
/**
* 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 lombok.NoArgsConstructor;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.event.ErrorEvent;
import org.thingsboard.server.common.data.event.StatisticsEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseEntity;
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.ERROR_EVENT_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_METHOD_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.STATS_EVENT_TABLE_NAME;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ERROR_EVENT_TABLE_NAME)
@NoArgsConstructor
public class ErrorEventEntity extends EventEntity<ErrorEvent> implements BaseEntity<ErrorEvent> {
@Column(name = EVENT_METHOD_COLUMN_NAME)
private String method;
@Column(name = EVENT_ERROR_COLUMN_NAME)
private String error;
public ErrorEventEntity(ErrorEvent event) {
super(event);
this.method = event.getMethod();
this.error = event.getError();
}
@Override
public ErrorEvent toData() {
return ErrorEvent.builder()
.tenantId(TenantId.fromUUID(tenantId))
.entityId(entityId)
.serviceId(serviceId)
.id(id)
.ts(ts)
.method(method)
.error(error)
.build();
}
}

114
dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java

@ -15,104 +15,80 @@
*/
package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EventId;
import org.thingsboard.server.common.data.id.TenantId;
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.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_BODY_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SERVICE_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_UID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = EVENT_COLUMN_FAMILY_NAME)
@NoArgsConstructor
public class EventEntity extends BaseSqlEntity<Event> implements BaseEntity<Event> {
@MappedSuperclass
public abstract class EventEntity<T extends Event> implements BaseEntity<T> {
@Column(name = EVENT_TENANT_ID_PROPERTY)
private UUID tenantId;
@Id
@Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "uuid")
protected UUID id;
@Enumerated(EnumType.STRING)
@Column(name = EVENT_ENTITY_TYPE_PROPERTY)
private EntityType entityType;
@Column(name = EVENT_TENANT_ID_PROPERTY, columnDefinition = "uuid")
protected UUID tenantId;
@Column(name = EVENT_ENTITY_ID_PROPERTY)
private UUID entityId;
@Column(name = EVENT_ENTITY_ID_PROPERTY, columnDefinition = "uuid")
protected UUID entityId;
@Column(name = EVENT_TYPE_PROPERTY)
private String eventType;
@Column(name = EVENT_SERVICE_ID_PROPERTY)
protected String serviceId;
@Column(name = EVENT_UID_PROPERTY)
private String eventUid;
@Column(name = TS_COLUMN)
protected long ts;
@Type(type = "json")
@Column(name = EVENT_BODY_PROPERTY)
private JsonNode body;
public EventEntity(UUID id, UUID tenantId, UUID entityId, String serviceId, long ts) {
this.id = id;
this.tenantId = tenantId;
this.entityId = entityId;
this.serviceId = serviceId;
this.ts = ts;
}
@Column(name = TS_COLUMN)
private long ts;
public EventEntity(EventInfo event) {
if (event.getId() != null) {
this.setUuid(event.getId().getId());
this.ts = getTs(event.getId().getId());
} else {
this.ts = System.currentTimeMillis();
}
this.setCreatedTime(event.getCreatedTime());
if (event.getTenantId() != null) {
this.tenantId = event.getTenantId().getId();
}
if (event.getEntityId() != null) {
this.entityType = event.getEntityId().getEntityType();
this.entityId = event.getEntityId().getId();
}
this.eventType = event.getType();
this.eventUid = event.getUid();
this.body = event.getBody();
public EventEntity(Event event) {
this.id = event.getId().getId();
this.tenantId = event.getTenantId().getId();
this.entityId = event.getEntityId();
this.serviceId = event.getServiceId();
this.ts = event.getCreatedTime();
}
@Override
public UUID getUuid() {
return id;
}
@Override
public void setUuid(UUID id) {
this.id = id;
}
@Override
public Event toData() {
EventInfo event = new EventInfo(new EventId(this.getUuid()));
event.setCreatedTime(createdTime);
event.setTenantId(TenantId.fromUUID(tenantId));
event.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
event.setBody(body);
event.setType(eventType);
event.setUid(eventUid);
return null;
public long getCreatedTime() {
return ts;
}
private static long getTs(UUID uuid) {
return (uuid.timestamp() - EPOCH_DIFF) / 10000;
@Override
public void setCreatedTime(long createdTime) {
ts = createdTime;
}
}

72
dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java

@ -0,0 +1,72 @@
/**
* 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 lombok.NoArgsConstructor;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.event.LifecycleEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.LC_EVENT_TABLE_NAME;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = LC_EVENT_TABLE_NAME)
@NoArgsConstructor
public class LifecycleEventEntity extends EventEntity<LifecycleEvent> implements BaseEntity<LifecycleEvent> {
@Column(name = EVENT_TYPE_COLUMN_NAME)
private String eventType;
@Column(name = EVENT_SUCCESS_COLUMN_NAME)
private boolean success;
@Column(name = EVENT_ERROR_COLUMN_NAME)
private String error;
public LifecycleEventEntity(LifecycleEvent event) {
super(event);
this.eventType = event.getLcEventType();
this.success = event.isSuccess();
this.error = event.getError();
}
@Override
public LifecycleEvent toData() {
return LifecycleEvent.builder()
.tenantId(TenantId.fromUUID(tenantId))
.entityId(entityId)
.serviceId(serviceId)
.id(id)
.ts(ts)
.lcEventType(eventType)
.success(success)
.error(error)
.build();
}
}

72
dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java

@ -0,0 +1,72 @@
/**
* 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 lombok.NoArgsConstructor;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.event.LifecycleEvent;
import org.thingsboard.server.common.data.event.StatisticsEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERRORS_OCCURRED_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MESSAGES_PROCESSED_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_COLUMN_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.LC_EVENT_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.STATS_EVENT_TABLE_NAME;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = STATS_EVENT_TABLE_NAME)
@NoArgsConstructor
public class StatisticsEventEntity extends EventEntity<StatisticsEvent> implements BaseEntity<StatisticsEvent> {
@Column(name = EVENT_MESSAGES_PROCESSED_COLUMN_NAME)
private long messagesProcessed;
@Column(name = EVENT_ERRORS_OCCURRED_COLUMN_NAME)
private long errorsOccurred;
public StatisticsEventEntity(StatisticsEvent event) {
super(event);
this.messagesProcessed = event.getMessagesProcessed();
this.errorsOccurred = event.getErrorsOccurred();
}
@Override
public StatisticsEvent toData() {
return StatisticsEvent.builder()
.tenantId(TenantId.fromUUID(tenantId))
.entityId(entityId)
.serviceId(serviceId)
.id(id)
.ts(ts)
.messagesProcessed(messagesProcessed)
.errorsOccurred(errorsOccurred)
.build();
}
}

74
dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java

@ -0,0 +1,74 @@
/**
* 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.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.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.ErrorEventEntity;
import org.thingsboard.server.dao.model.sql.LifecycleEventEntity;
import org.thingsboard.server.dao.model.sql.StatisticsEventEntity;
import java.util.UUID;
/**
* Created by Valerii Sosliuk on 5/3/2017.
*/
public interface ErrorEventRepository extends JpaRepository<ErrorEventEntity, UUID> {
@Query("SELECT e FROM ErrorEventEntity 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<ErrorEventEntity> 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 error_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 (:method IS NULL OR e.e_method ILIKE concat('%', :method, '%')) " +
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))"
,
countQuery = "SELECT count(*) FROM error_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 (:method IS NULL OR e.e_method ILIKE concat('%', :method, '%')) " +
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))"
)
Page<ErrorEventEntity> findEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
@Param("serviceId") String server,
@Param("method") String method,
@Param("error") String error,
Pageable pageable);
}

8
dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java

@ -73,7 +73,7 @@ public class EventInsertRepository {
" (id, tenant_id, ts, entity_id, service_id, e_type, e_success, e_error) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;");
insertStmtMap.put(EventType.STATS, "INSERT INTO " + EventType.STATS.getTable() +
" (id, tenant_id, ts, entity_id, service_id, e_messages_processed, e_errors_occured) " +
" (id, tenant_id, ts, entity_id, service_id, e_messages_processed, e_errors_occurred) " +
"VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING;");
insertStmtMap.put(EventType.DEBUG_RULE_NODE, "INSERT INTO " + EventType.DEBUG_RULE_NODE.getTable() +
" (id, tenant_id, ts, entity_id, service_id, e_type, e_entity_id, e_entity_type, e_msg_id, e_msg_type, e_data_type, e_relation_type, e_data, e_metadata, e_error) " +
@ -171,8 +171,8 @@ public class EventInsertRepository {
RuleNodeDebugEvent event = (RuleNodeDebugEvent) events.get(i);
setCommonEventFields(ps, event);
safePutString(ps, 6, event.getEventType());
safePutUUID(ps, 7, event.getEntityId() != null ? event.getEntityId().getId() : null);
safePutString(ps, 8, event.getEntityId() != null ? event.getEntityId().getEntityType().name() : null);
safePutUUID(ps, 7, event.getEventEntity() != null ? event.getEventEntity().getId() : null);
safePutString(ps, 8, event.getEventEntity() != null ? event.getEventEntity().getEntityType().name() : null);
safePutUUID(ps, 9, event.getMsgId());
safePutString(ps, 10, event.getMsgType());
safePutString(ps, 11, event.getDataType());
@ -226,7 +226,7 @@ public class EventInsertRepository {
ps.setObject(1, event.getId().getId());
ps.setObject(2, event.getTenantId().getId());
ps.setLong(3, event.getCreatedTime());
ps.setObject(4, event.getEntityId().getId());
ps.setObject(4, event.getEntityId());
ps.setString(5, event.getServiceId());
}

384
dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java

@ -31,214 +31,178 @@ import java.util.UUID;
*/
public interface EventRepository extends JpaRepository<EventEntity, UUID> {
EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId,
EntityType entityType,
UUID entityId,
String eventType,
String eventUid);
EventEntity findByTenantIdAndEntityTypeAndEntityId(UUID tenantId,
EntityType entityType,
UUID entityId);
@Query("SELECT e FROM EventEntity e WHERE e.tenantId = :tenantId AND e.entityType = :entityType " +
"AND e.entityId = :entityId AND e.eventType = :eventType ORDER BY e.eventType DESC, e.id DESC")
List<EventEntity> findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType(
@Param("tenantId") UUID tenantId,
@Param("entityType") EntityType entityType,
@Param("entityId") UUID entityId,
@Param("eventType") String eventType,
Pageable pageable);
@Query("SELECT e FROM EventEntity e WHERE " +
"e.tenantId = :tenantId " +
"AND e.entityType = :entityType AND e.entityId = :entityId " +
"AND (:startTime IS NULL OR e.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR e.createdTime <= :endTime) " +
"AND LOWER(e.eventType) LIKE LOWER(CONCAT('%', :textSearch, '%'))"
)
Page<EventEntity> findEventsByTenantIdAndEntityId(@Param("tenantId") UUID tenantId,
@Param("entityType") EntityType entityType,
@Param("entityId") UUID entityId,
@Param("textSearch") String textSearch,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
Pageable pageable);
@Query("SELECT e FROM EventEntity e WHERE " +
"e.tenantId = :tenantId " +
"AND e.entityType = :entityType AND e.entityId = :entityId " +
"AND e.eventType = :eventType " +
"AND (:startTime IS NULL OR e.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR e.createdTime <= :endTime)"
)
Page<EventEntity> findEventsByTenantIdAndEntityIdAndEventType(@Param("tenantId") UUID tenantId,
@Param("entityType") EntityType entityType,
@Param("entityId") UUID entityId,
@Param("eventType") String eventType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = :eventType " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:type IS NULL OR lower(json_body->>'type') LIKE concat('%', lower(:type\\:\\:varchar), '%')) " +
"AND (:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:entityName IS NULL OR lower(json_body->>'entityName') LIKE concat('%', lower(:entityName\\:\\:varchar), '%')) " +
"AND (:relationType IS NULL OR lower(json_body->>'relationType') LIKE concat('%', lower(:relationType\\:\\:varchar), '%')) " +
"AND (:bodyEntityId IS NULL OR lower(json_body->>'entityId') LIKE concat('%', lower(:bodyEntityId\\:\\:varchar), '%')) " +
"AND (:msgType IS NULL OR lower(json_body->>'msgType') LIKE concat('%', lower(:msgType\\:\\:varchar), '%')) " +
"AND ((:isError = FALSE) OR (json_body->>'error') IS NOT NULL) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%')) " +
"AND (:data IS NULL OR lower(json_body->>'data') LIKE concat('%', lower(:data\\:\\:varchar), '%')) " +
"AND (:metadata IS NULL OR lower(json_body->>'metadata') LIKE concat('%', lower(:metadata\\:\\:varchar), '%')) ",
countQuery = "SELECT count(*) FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = :eventType " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:type IS NULL OR lower(json_body->>'type') LIKE concat('%', lower(:type\\:\\:varchar), '%')) " +
"AND (:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:entityName IS NULL OR lower(json_body->>'entityName') LIKE concat('%', lower(:entityName\\:\\:varchar), '%')) " +
"AND (:relationType IS NULL OR lower(json_body->>'relationType') LIKE concat('%', lower(:relationType\\:\\:varchar), '%')) " +
"AND (:bodyEntityId IS NULL OR lower(json_body->>'entityId') LIKE concat('%', lower(:bodyEntityId\\:\\:varchar), '%')) " +
"AND (:msgType IS NULL OR lower(json_body->>'msgType') LIKE concat('%', lower(:msgType\\:\\:varchar), '%')) " +
"AND ((:isError = FALSE) OR (json_body->>'error') IS NOT NULL) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%')) " +
"AND (:data IS NULL OR lower(json_body->>'data') LIKE concat('%', lower(:data\\:\\:varchar), '%')) " +
"AND (:metadata IS NULL OR lower(json_body->>'metadata') LIKE concat('%', lower(:metadata\\:\\:varchar), '%'))"
)
Page<EventEntity> findDebugRuleNodeEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("entityType") String entityType,
@Param("eventType") String eventType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
@Param("type") String type,
@Param("server") String server,
@Param("entityName") String entityName,
@Param("relationType") String relationType,
@Param("bodyEntityId") String bodyEntityId,
@Param("msgType") String msgType,
@Param("isError") boolean isError,
@Param("error") String error,
@Param("data") String data,
@Param("metadata") String metadata,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'ERROR' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:method IS NULL OR lower(json_body->>'method') LIKE concat('%', lower(:method\\:\\:varchar), '%')) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))",
countQuery = "SELECT count(*) FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'ERROR' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:method IS NULL OR lower(json_body->>'method') LIKE concat('%', lower(:method\\:\\:varchar), '%')) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))")
Page<EventEntity> findErrorEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("entityType") String entityType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTIme,
@Param("server") String server,
@Param("method") String method,
@Param("error") String error,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'LC_EVENT' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:event IS NULL OR lower(json_body->>'event') LIKE concat('%', lower(:event\\:\\:varchar), '%')) " +
"AND ((:statusFilterEnabled = FALSE) OR lower(json_body->>'success')\\:\\:boolean = :statusFilter) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))"
,
countQuery = "SELECT count(*) FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'LC_EVENT' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:event IS NULL OR lower(json_body->>'event') LIKE concat('%', lower(:event\\:\\:varchar), '%')) " +
"AND ((:statusFilterEnabled = FALSE) OR lower(json_body->>'success')\\:\\:boolean = :statusFilter) " +
"AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))"
)
Page<EventEntity> findLifeCycleEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("entityType") String entityType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTIme,
@Param("server") String server,
@Param("event") String event,
@Param("statusFilterEnabled") boolean statusFilterEnabled,
@Param("statusFilter") boolean statusFilter,
@Param("error") String error,
Pageable pageable);
@Query(nativeQuery = true,
value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'STATS' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(e.body\\:\\:json->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:messagesProcessed = 0 OR (json_body->>'messagesProcessed')\\:\\:integer >= :messagesProcessed) " +
"AND (:errorsOccurred = 0 OR (json_body->>'errorsOccurred')\\:\\:integer >= :errorsOccurred) ",
countQuery = "SELECT count(*) FROM " +
"(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
"e.tenant_id = :tenantId " +
"AND e.entity_type = :entityType " +
"AND e.entity_id = :entityId " +
"AND e.event_type = 'LC_EVENT' " +
"AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
") AS e WHERE " +
"(:server IS NULL OR lower(e.body\\:\\:json->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
"AND (:messagesProcessed = 0 OR (json_body->>'messagesProcessed')\\:\\:integer >= :messagesProcessed) " +
"AND (:errorsOccurred = 0 OR (json_body->>'errorsOccurred')\\:\\:integer >= :errorsOccurred) ")
Page<EventEntity> findStatisticsEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("entityType") String entityType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTIme,
@Param("server") String server,
@Param("messagesProcessed") Integer messagesProcessed,
@Param("errorsOccurred") Integer errorsOccurred,
Pageable pageable);
// EventEntity findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(UUID tenantId,
// EntityType entityType,
// UUID entityId,
// String eventType,
// String eventUid);
//
// EventEntity findByTenantIdAndEntityTypeAndEntityId(UUID tenantId,
// EntityType entityType,
// UUID entityId);
//
// @Query("SELECT e FROM EventEntity e WHERE e.tenantId = :tenantId AND e.entityType = :entityType " +
// "AND e.entityId = :entityId AND e.eventType = :eventType ORDER BY e.eventType DESC, e.id DESC")
// List<EventEntity> findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType(
// @Param("tenantId") UUID tenantId,
// @Param("entityType") EntityType entityType,
// @Param("entityId") UUID entityId,
// @Param("eventType") String eventType,
// Pageable pageable);
//
// @Query("SELECT e FROM EventEntity e WHERE " +
// "e.tenantId = :tenantId " +
// "AND e.entityType = :entityType AND e.entityId = :entityId " +
// "AND (:startTime IS NULL OR e.createdTime >= :startTime) " +
// "AND (:endTime IS NULL OR e.createdTime <= :endTime) " +
// "AND LOWER(e.eventType) LIKE LOWER(CONCAT('%', :textSearch, '%'))"
// )
// Page<EventEntity> findEventsByTenantIdAndEntityId(@Param("tenantId") UUID tenantId,
// @Param("entityType") EntityType entityType,
// @Param("entityId") UUID entityId,
// @Param("textSearch") String textSearch,
// @Param("startTime") Long startTime,
// @Param("endTime") Long endTime,
// Pageable pageable);
//
//
//
// @Query("SELECT e FROM EventEntity e WHERE " +
// "e.tenantId = :tenantId " +
// "AND e.entityType = :entityType AND e.entityId = :entityId " +
// "AND e.eventType = :eventType " +
// "AND (:startTime IS NULL OR e.createdTime >= :startTime) " +
// "AND (:endTime IS NULL OR e.createdTime <= :endTime)"
// )
// Page<EventEntity> findEventsByTenantIdAndEntityIdAndEventType(@Param("tenantId") UUID tenantId,
// @Param("entityType") EntityType entityType,
// @Param("entityId") UUID entityId,
// @Param("eventType") String eventType,
// @Param("startTime") Long startTime,
// @Param("endTime") Long endTime,
// Pageable pageable);
//
// @Query(nativeQuery = true,
// value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = :eventType " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:type IS NULL OR lower(json_body->>'type') LIKE concat('%', lower(:type\\:\\:varchar), '%')) " +
// "AND (:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:entityName IS NULL OR lower(json_body->>'entityName') LIKE concat('%', lower(:entityName\\:\\:varchar), '%')) " +
// "AND (:relationType IS NULL OR lower(json_body->>'relationType') LIKE concat('%', lower(:relationType\\:\\:varchar), '%')) " +
// "AND (:bodyEntityId IS NULL OR lower(json_body->>'entityId') LIKE concat('%', lower(:bodyEntityId\\:\\:varchar), '%')) " +
// "AND (:msgType IS NULL OR lower(json_body->>'msgType') LIKE concat('%', lower(:msgType\\:\\:varchar), '%')) " +
// "AND ((:isError = FALSE) OR (json_body->>'error') IS NOT NULL) " +
// "AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%')) " +
// "AND (:data IS NULL OR lower(json_body->>'data') LIKE concat('%', lower(:data\\:\\:varchar), '%')) " +
// "AND (:metadata IS NULL OR lower(json_body->>'metadata') LIKE concat('%', lower(:metadata\\:\\:varchar), '%')) ",
// countQuery = "SELECT count(*) FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = :eventType " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:type IS NULL OR lower(json_body->>'type') LIKE concat('%', lower(:type\\:\\:varchar), '%')) " +
// "AND (:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:entityName IS NULL OR lower(json_body->>'entityName') LIKE concat('%', lower(:entityName\\:\\:varchar), '%')) " +
// "AND (:relationType IS NULL OR lower(json_body->>'relationType') LIKE concat('%', lower(:relationType\\:\\:varchar), '%')) " +
// "AND (:bodyEntityId IS NULL OR lower(json_body->>'entityId') LIKE concat('%', lower(:bodyEntityId\\:\\:varchar), '%')) " +
// "AND (:msgType IS NULL OR lower(json_body->>'msgType') LIKE concat('%', lower(:msgType\\:\\:varchar), '%')) " +
// "AND ((:isError = FALSE) OR (json_body->>'error') IS NOT NULL) " +
// "AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%')) " +
// "AND (:data IS NULL OR lower(json_body->>'data') LIKE concat('%', lower(:data\\:\\:varchar), '%')) " +
// "AND (:metadata IS NULL OR lower(json_body->>'metadata') LIKE concat('%', lower(:metadata\\:\\:varchar), '%'))"
// )
// Page<EventEntity> findDebugRuleNodeEvents(@Param("tenantId") UUID tenantId,
// @Param("entityId") UUID entityId,
// @Param("entityType") String entityType,
// @Param("eventType") String eventType,
// @Param("startTime") Long startTime,
// @Param("endTime") Long endTime,
// @Param("type") String type,
// @Param("server") String server,
// @Param("entityName") String entityName,
// @Param("relationType") String relationType,
// @Param("bodyEntityId") String bodyEntityId,
// @Param("msgType") String msgType,
// @Param("isError") boolean isError,
// @Param("error") String error,
// @Param("data") String data,
// @Param("metadata") String metadata,
// Pageable pageable);
//
// @Query(nativeQuery = true,
// value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = 'ERROR' " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:method IS NULL OR lower(json_body->>'method') LIKE concat('%', lower(:method\\:\\:varchar), '%')) " +
// "AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))",
// countQuery = "SELECT count(*) FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = 'ERROR' " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:server IS NULL OR lower(json_body->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:method IS NULL OR lower(json_body->>'method') LIKE concat('%', lower(:method\\:\\:varchar), '%')) " +
// "AND (:error IS NULL OR lower(json_body->>'error') LIKE concat('%', lower(:error\\:\\:varchar), '%'))")
// Page<EventEntity> findErrorEvents(@Param("tenantId") UUID tenantId,
// @Param("entityId") UUID entityId,
// @Param("entityType") String entityType,
// @Param("startTime") Long startTime,
// @Param("endTime") Long endTIme,
// @Param("server") String server,
// @Param("method") String method,
// @Param("error") String error,
// Pageable pageable);
//
//
// @Query(nativeQuery = true,
// value = "SELECT e.id, e.created_time, e.body, e.entity_id, e.entity_type, e.event_type, e.event_uid, e.tenant_id, ts FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = 'STATS' " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:server IS NULL OR lower(e.body\\:\\:json->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:messagesProcessed = 0 OR (json_body->>'messagesProcessed')\\:\\:integer >= :messagesProcessed) " +
// "AND (:errorsOccurred = 0 OR (json_body->>'errorsOccurred')\\:\\:integer >= :errorsOccurred) ",
// countQuery = "SELECT count(*) FROM " +
// "(SELECT *, e.body\\:\\:jsonb as json_body FROM event e WHERE " +
// "e.tenant_id = :tenantId " +
// "AND e.entity_type = :entityType " +
// "AND e.entity_id = :entityId " +
// "AND e.event_type = 'LC_EVENT' " +
// "AND e.created_time >= :startTime AND (:endTime = 0 OR e.created_time <= :endTime) " +
// ") AS e WHERE " +
// "(:server IS NULL OR lower(e.body\\:\\:json->>'server') LIKE concat('%', lower(:server\\:\\:varchar), '%')) " +
// "AND (:messagesProcessed = 0 OR (json_body->>'messagesProcessed')\\:\\:integer >= :messagesProcessed) " +
// "AND (:errorsOccurred = 0 OR (json_body->>'errorsOccurred')\\:\\:integer >= :errorsOccurred) ")
// Page<EventEntity> findStatisticsEvents(@Param("tenantId") UUID tenantId,
// @Param("entityId") UUID entityId,
// @Param("entityType") String entityType,
// @Param("startTime") Long startTime,
// @Param("endTime") Long endTIme,
// @Param("server") String server,
// @Param("messagesProcessed") Integer messagesProcessed,
// @Param("errorsOccurred") Integer errorsOccurred,
// Pageable pageable);
//
}

148
dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java

@ -18,21 +18,22 @@ package org.thingsboard.server.dao.sql.event;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.event.DebugEvent;
import org.thingsboard.server.common.data.event.ErrorEvent;
import org.thingsboard.server.common.data.event.ErrorEventFilter;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.event.EventFilter;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.event.LifeCycleEventFilter;
import org.thingsboard.server.common.data.event.LifecycleEvent;
import org.thingsboard.server.common.data.event.StatisticsEvent;
import org.thingsboard.server.common.data.event.StatisticsEventFilter;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EventId;
@ -41,22 +42,14 @@ import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.stats.StatsFactory;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.event.EventDao;
import org.thingsboard.server.dao.model.sql.EventEntity;
import org.thingsboard.server.dao.sql.JpaAbstractDao;
import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent;
import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams;
import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper;
import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository;
import org.thingsboard.server.dao.timeseries.SqlPartition;
import org.thingsboard.server.dao.timeseries.SqlTsPartitionDate;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@ -72,7 +65,7 @@ import java.util.function.Function;
*/
@Slf4j
@Component
public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implements EventDao {
public class JpaBaseEventDao implements EventDao {
private static final long PARTITION_DURATION = TimeUnit.HOURS.toMillis(1);
private final Map<EventType, Map<Long, SqlPartition>> partitionsByEventType = new ConcurrentHashMap<>();
@ -85,20 +78,19 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
private EventRepository eventRepository;
@Autowired
private EventInsertRepository eventInsertRepository;
private LifecycleEventRepository lcEventRepository;
@Autowired
private EventCleanupRepository eventCleanupRepository;
private StatisticsEventRepository statsEventRepository;
@Override
protected Class<EventEntity> getEntityClass() {
return EventEntity.class;
}
@Autowired
private ErrorEventRepository errorEventRepository;
@Override
protected JpaRepository<EventEntity, UUID> getRepository() {
return eventRepository;
}
@Autowired
private EventInsertRepository eventInsertRepository;
@Autowired
private EventCleanupRepository eventCleanupRepository;
@Autowired
ScheduledLogExecutorComponent logExecutor;
@ -198,13 +190,6 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
}
}
@Override
public EventInfo findEvent(UUID tenantId, EntityId entityId, String eventType, String eventUid) {
return null;
// return DaoUtil.getData(eventRepository.findByTenantIdAndEntityTypeAndEntityIdAndEventTypeAndEventUid(
// tenantId, entityId.getEntityType(), entityId.getId(), eventType, eventUid));
}
@Override
public PageData<EventInfo> findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) {
return null;
@ -221,22 +206,37 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
}
@Override
public PageData<EventInfo> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
return null;
// return DaoUtil.toPageData(
// eventRepository
// .findEventsByTenantIdAndEntityIdAndEventType(
// tenantId,
// entityId.getEntityType(),
// entityId.getId(),
// eventType,
// pageLink.getStartTime(),
// pageLink.getEndTime(),
// DaoUtil.toPageable(pageLink)));
public PageData<? extends Event> findEvents(UUID tenantId, UUID entityId, EventType eventType, TimePageLink pageLink) {
switch (eventType) {
case LC_EVENT:
return findLcEventsWithoutFilter(tenantId, entityId, pageLink);
case STATS:
return findStatsEventsWithoutFilter(tenantId, entityId, pageLink);
case ERROR:
return findErrorEventsWithoutFilter(tenantId, entityId, pageLink);
default:
throw new RuntimeException("Event type: " + eventType + " is not supported!");
}
}
private PageData<LifecycleEvent> findLcEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) {
return DaoUtil.toPageData(
lcEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink)));
}
private PageData<StatisticsEvent> findStatsEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) {
return DaoUtil.toPageData(
statsEventRepository.findEventsWithoutFilter(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink)));
}
private PageData<ErrorEvent> findErrorEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) {
return DaoUtil.toPageData(
errorEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<EventInfo> findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) {
public PageData<? extends Event> findEventByFilter(UUID tenantId, UUID entityId, EventFilter eventFilter, TimePageLink pageLink) {
if (eventFilter.hasFilterForJsonBody()) {
switch (eventFilter.getEventType()) {
case DEBUG_RULE_NODE:
@ -252,7 +252,7 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
throw new RuntimeException("Not supported event type: " + eventFilter.getEventType());
}
} else {
return findEvents(tenantId, entityId, eventFilter.getEventType().name(), pageLink);
return findEvents(tenantId, entityId, eventFilter.getEventType(), pageLink);
}
}
@ -279,40 +279,36 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
// DaoUtil.toPageable(pageLink)));
}
private PageData<EventInfo> findEventByFilter(UUID tenantId, EntityId entityId, ErrorEventFilter eventFilter, TimePageLink pageLink) {
return null;
// return DaoUtil.toPageData(
// eventRepository.findErrorEvents(
// tenantId,
// entityId.getId(),
// entityId.getEntityType().name(),
// notNull(pageLink.getStartTime()),
// notNull(pageLink.getEndTime()),
// eventFilter.getServer(),
// eventFilter.getMethod(),
// eventFilter.getErrorStr(),
// DaoUtil.toPageable(pageLink))
// );
private PageData<? extends Event> findEventByFilter(UUID tenantId, UUID entityId, ErrorEventFilter eventFilter, TimePageLink pageLink) {
return DaoUtil.toPageData(
errorEventRepository.findEvents(
tenantId,
entityId,
pageLink.getStartTime(),
pageLink.getEndTime(),
eventFilter.getServer(),
eventFilter.getMethod(),
eventFilter.getErrorStr(),
DaoUtil.toPageable(pageLink))
);
}
private PageData<EventInfo> findEventByFilter(UUID tenantId, EntityId entityId, LifeCycleEventFilter eventFilter, TimePageLink pageLink) {
return null;
// boolean statusFilterEnabled = !StringUtils.isEmpty(eventFilter.getStatus());
// boolean statusFilter = statusFilterEnabled && eventFilter.getStatus().equalsIgnoreCase("Success");
// return DaoUtil.toPageData(
// eventRepository.findLifeCycleEvents(
// tenantId,
// entityId.getId(),
// entityId.getEntityType().name(),
// notNull(pageLink.getStartTime()),
// notNull(pageLink.getEndTime()),
// eventFilter.getServer(),
// eventFilter.getEvent(),
// statusFilterEnabled,
// statusFilter,
// eventFilter.getErrorStr(),
// DaoUtil.toPageable(pageLink))
// );
private PageData<? extends Event> findEventByFilter(UUID tenantId, UUID entityId, LifeCycleEventFilter eventFilter, TimePageLink pageLink) {
boolean statusFilterEnabled = !StringUtils.isEmpty(eventFilter.getStatus());
boolean statusFilter = statusFilterEnabled && eventFilter.getStatus().equalsIgnoreCase("Success");
return DaoUtil.toPageData(
lcEventRepository.findEvents(
tenantId,
entityId,
pageLink.getStartTime(),
pageLink.getEndTime(),
eventFilter.getServer(),
eventFilter.getEvent(),
statusFilterEnabled,
statusFilter,
eventFilter.getErrorStr(),
DaoUtil.toPageable(pageLink))
);
}
private PageData<EventInfo> findEventByFilter(UUID tenantId, EntityId entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) {
@ -332,7 +328,7 @@ public class JpaBaseEventDao extends JpaAbstractDao<EventEntity, Event> implemen
}
@Override
public List<EventInfo> findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit) {
public List<EventInfo> findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit) {
return null;
// List<EventEntity> latest = eventRepository.findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType(
// tenantId,

76
dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java

@ -0,0 +1,76 @@
/**
* 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.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.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.LifecycleEventEntity;
import java.util.UUID;
/**
* Created by Valerii Sosliuk on 5/3/2017.
*/
public interface LifecycleEventRepository extends JpaRepository<LifecycleEventEntity, UUID> {
@Query("SELECT e FROM LifecycleEventEntity 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<LifecycleEventEntity> 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 lc_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 (:eventType IS NULL OR e.e_type ILIKE concat('%', :eventType, '%')) " +
"AND ((:statusFilterEnabled = FALSE) OR e.e_success = :statusFilter) " +
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))"
,
countQuery = "SELECT count(*) FROM lc_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 (:eventType IS NULL OR e.e_type ILIKE concat('%', :eventType, '%')) " +
"AND ((:statusFilterEnabled = FALSE) OR e.e_success = :statusFilter) " +
"AND (:error IS NULL OR e.e_error ILIKE concat('%', :error, '%'))"
)
Page<LifecycleEventEntity> findEvents(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
@Param("serviceId") String server,
@Param("eventType") String eventType,
@Param("statusFilterEnabled") boolean statusFilterEnabled,
@Param("statusFilter") boolean statusFilter,
@Param("error") String error,
Pageable pageable);
}

46
dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java

@ -0,0 +1,46 @@
/**
* 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.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.Query;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.event.StatisticsEvent;
import org.thingsboard.server.dao.model.sql.LifecycleEventEntity;
import org.thingsboard.server.dao.model.sql.StatisticsEventEntity;
import java.util.UUID;
/**
* Created by Valerii Sosliuk on 5/3/2017.
*/
public interface StatisticsEventRepository extends JpaRepository<StatisticsEventEntity, UUID> {
@Query("SELECT e FROM StatisticsEventEntity 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<StatisticsEventEntity> findEventsWithoutFilter(@Param("tenantId") UUID tenantId,
@Param("entityId") UUID entityId,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
Pageable pageable);
}

24
dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql

@ -21,18 +21,18 @@
-- That difference between NULLS LAST and NULLS FIRST prevents to hit index while querying latest by ts
-- That why we need to define DESC index explicitly as (ts DESC NULLS LAST)
CREATE INDEX IF NOT EXISTS idx_event_ts
ON public.event
(ts DESC NULLS LAST)
WITH (FILLFACTOR=95);
CREATE INDEX IF NOT EXISTS idx_rule_node_debug_event_main
ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95);
COMMENT ON INDEX public.idx_event_ts
IS 'This index helps to delete events by TTL using timestamp';
CREATE INDEX IF NOT EXISTS idx_rule_chain_debug_event_main
ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95);
CREATE INDEX IF NOT EXISTS idx_event_tenant_entity_type_entity_event_type_created_time_des
ON public.event
(tenant_id ASC, entity_type ASC, entity_id ASC, event_type ASC, created_time DESC NULLS LAST)
WITH (FILLFACTOR=95);
CREATE INDEX IF NOT EXISTS idx_stats_event_main
ON stats_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95);
CREATE INDEX IF NOT EXISTS idx_lc_event_main
ON lc_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95);
CREATE INDEX IF NOT EXISTS idx_error_event_main
ON error_event (tenant_id ASC, entity_id ASC, ts DESC) WITH (FILLFACTOR=95);
COMMENT ON INDEX public.idx_event_tenant_entity_type_entity_event_type_created_time_des
IS 'This index helps to open latest events on UI fast';

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

@ -324,7 +324,7 @@ CREATE TABLE IF NOT EXISTS device_credentials (
);
CREATE TABLE IF NOT EXISTS rule_node_debug_event (
id uuid NOT NULL CONSTRAINT rule_node_debug_event_pkey PRIMARY KEY,
id uuid NOT NULL,
tenant_id uuid NOT NULL ,
ts bigint NOT NULL,
entity_id uuid NOT NULL,
@ -342,7 +342,7 @@ CREATE TABLE IF NOT EXISTS rule_node_debug_event (
) PARTITION BY RANGE (ts);
CREATE TABLE IF NOT EXISTS rule_chain_debug_event (
id uuid NOT NULL CONSTRAINT rule_chain_debug_event_pkey PRIMARY KEY,
id uuid NOT NULL,
tenant_id uuid NOT NULL,
ts bigint NOT NULL,
entity_id uuid NOT NULL,
@ -352,17 +352,17 @@ CREATE TABLE IF NOT EXISTS rule_chain_debug_event (
) PARTITION BY RANGE (ts);
CREATE TABLE IF NOT EXISTS stats_event (
id uuid NOT NULL CONSTRAINT stats_event_pkey PRIMARY KEY,
id uuid NOT NULL,
tenant_id uuid NOT NULL,
ts bigint NOT NULL,
entity_id uuid NOT NULL,
service_id varchar NOT NULL,
e_messages_processed bigint NOT NULL,
e_errors_occured bigint NOT NULL
e_errors_occurred bigint NOT NULL
) PARTITION BY RANGE (ts);
CREATE TABLE IF NOT EXISTS lc_event (
id uuid NOT NULL CONSTRAINT lc_event_pkey PRIMARY KEY,
id uuid NOT NULL,
tenant_id uuid NOT NULL,
ts bigint NOT NULL,
entity_id uuid NOT NULL,
@ -373,7 +373,7 @@ CREATE TABLE IF NOT EXISTS lc_event (
) PARTITION BY RANGE (ts);
CREATE TABLE IF NOT EXISTS error_event (
id uuid NOT NULL CONSTRAINT error_event_pkey PRIMARY KEY,
id uuid NOT NULL,
tenant_id uuid NOT NULL,
ts bigint NOT NULL,
entity_id uuid NOT NULL,

2
dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java

@ -194,7 +194,7 @@ public abstract class AbstractServiceTest {
}
return RuleNodeDebugEvent.builder()
.tenantId(tenantId)
.entityId(entityId)
.entityId(entityId.getId())
.serviceId("server A")
.data(JacksonUtil.toString(readFromResource("TestJsonData.json")))
.build();

11
dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java

@ -22,6 +22,7 @@ import org.junit.Test;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.Event;
import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.event.RuleNodeDebugEvent;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -80,8 +81,7 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest {
TimePageLink timePageLink = new TimePageLink(2, 0, "", new SortOrder("createdTime"), startTime, endTime);
PageData<EventInfo> events = eventService.findEvents(tenantId, customerId, DataConstants.STATS,
timePageLink);
PageData<EventInfo> events = eventService.findEvents(tenantId, customerId, EventType.STATS, timePageLink);
Assert.assertNotNull(events.getData());
Assert.assertTrue(events.getData().size() == 2);
@ -89,7 +89,7 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest {
Assert.assertTrue(events.getData().get(1).getUuidId().equals(savedEvent2.getUuidId()));
Assert.assertTrue(events.hasNext());
events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, timePageLink.nextPageLink());
events = eventService.findEvents(tenantId, customerId, EventType.STATS, timePageLink.nextPageLink());
Assert.assertNotNull(events.getData());
Assert.assertTrue(events.getData().size() == 1);
@ -111,8 +111,7 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest {
TimePageLink timePageLink = new TimePageLink(2, 0, "", new SortOrder("createdTime", SortOrder.Direction.DESC), startTime, endTime);
PageData<EventInfo> events = eventService.findEvents(tenantId, customerId, DataConstants.STATS,
timePageLink);
PageData<EventInfo> events = eventService.findEvents(tenantId, customerId, EventType.STATS, timePageLink);
Assert.assertNotNull(events.getData());
Assert.assertTrue(events.getData().size() == 2);
@ -120,7 +119,7 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest {
Assert.assertTrue(events.getData().get(1).getUuidId().equals(savedEvent2.getUuidId()));
Assert.assertTrue(events.hasNext());
events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, timePageLink.nextPageLink());
events = eventService.findEvents(tenantId, customerId, EventType.STATS, timePageLink.nextPageLink());
Assert.assertNotNull(events.getData());
Assert.assertTrue(events.getData().size() == 1);

20
dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java

@ -16,34 +16,14 @@
package org.thingsboard.server.dao.sql.event;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EventId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.AbstractJpaDaoTest;
import org.thingsboard.server.dao.event.EventDao;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.thingsboard.server.common.data.DataConstants.ALARM;
import static org.thingsboard.server.common.data.DataConstants.STATS;
/**
* Created by Valerii Sosliuk on 5/5/2017.
*/

Loading…
Cancel
Save