diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index e6f207d960..b4c308db86 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/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) { diff --git a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java index fa5dedf66f..247a6c62d0 100644 --- a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java +++ b/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()) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index bdf74c9055..d4199006d0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/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"; diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index dd6c05749f..45042dc883 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/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); + } + } diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 143844504a..bcca7965b3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/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 events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2); + List events = eventService.findLatestEvents(tenantId, ruleNodeId, EventType.DEBUG_RULE_NODE, 2); JsonNode result = null; if (events != null) { for (EventInfo event : events) { diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java index 7335c10d13..ca0d5a6215 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java +++ b/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 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 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 { diff --git a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java index c840cf4c9a..70cd292e00 100644 --- a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java +++ b/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 debugEvents = getEvents(tenantId, ruleChainFinal.getFirstRuleNodeId(), DataConstants.LC_EVENT, 1000) + List 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") diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 0d157e755d..b5f4c98e25 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/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 saveAsync(Event event); - Optional findEvent(TenantId tenantId, EntityId entityId, String eventType, String eventUid); + PageData findEvents(TenantId tenantId, EntityId entityId, EventType eventType, TimePageLink pageLink); - PageData findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink); - - PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink); - - List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit); + List findLatestEvents(TenantId tenantId, EntityId entityId, EventType eventType, int limit); PageData findEventsByFilter(TenantId tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index 1351621bf5..90d95fb561 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/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"; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java index 8e06177ca6..f811a118cf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEvent.java +++ b/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; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java index 9c013e1486..6e41a3750e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/Event.java +++ b/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 { - 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; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java index 8d58158521..5fa6fb7370 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventType.java +++ b/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; } } \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java index 217955af96..1e78df36a6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifecycleEvent.java +++ b/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; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java index ac8c16c2e5..52c961c1c8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEvent.java +++ b/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; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java index f9280d2d6b..891ece5f22 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEvent.java +++ b/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; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java index b0194762de..b574949cf8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEvent.java +++ b/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; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index d7f0885bdc..311af9af44 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/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 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 findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) { - return eventDao.findEvents(tenantId.getId(), entityId, pageLink); + public PageData findEvents(TenantId tenantId, EntityId entityId, EventType eventType, TimePageLink pageLink) { + return convert(entityId.getEntityType(), eventDao.findEvents(tenantId.getId(), entityId.getId(), eventType, pageLink)); } @Override - public PageData findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { - return eventDao.findEvents(tenantId.getId(), entityId, eventType, pageLink); - } - - @Override - public List findLatestEvents(TenantId tenantId, EntityId entityId, String eventType, int limit) { - return eventDao.findLatestEvents(tenantId.getId(), entityId, eventType, limit); + public List findLatestEvents(TenantId tenantId, EntityId entityId, EventType eventType, int limit) { + return eventDao.findLatestEvents(tenantId.getId(), entityId.getId(), eventType, limit); } @Override public PageData 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 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 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 convert(EntityType entityType, PageData 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()); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java b/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java index 30815bd15e..1878594fb4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/EventDao.java +++ b/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 { +public interface EventDao { /** * Save or update event object async @@ -40,17 +41,6 @@ public interface EventDao extends Dao { */ ListenableFuture 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 { * @param pageLink the pageLink * @return the event list */ - PageData findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink); + PageData findEvents(UUID tenantId, UUID entityId, EventType eventType, TimePageLink pageLink); - PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink); + PageData 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 { * @param limit the limit * @return the event list */ - List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit); + List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit); /** * Executes stored procedure to cleanup old events. Uses separate ttl for debug and other events. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 0b4a65f43c..37934ed306 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/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"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java new file mode 100644 index 0000000000..397824140f --- /dev/null +++ b/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 implements BaseEntity { + + @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(); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java index bf08333e7b..b0a0135849 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java +++ b/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 implements BaseEntity { +@MappedSuperclass +public abstract class EventEntity implements BaseEntity { - @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; } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java new file mode 100644 index 0000000000..0a4380cb63 --- /dev/null +++ b/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 implements BaseEntity { + + @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(); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java new file mode 100644 index 0000000000..240e6fdcf7 --- /dev/null +++ b/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 implements BaseEntity { + + @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(); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/ErrorEventRepository.java new file mode 100644 index 0000000000..721ffe42fe --- /dev/null +++ b/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 { + + @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 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 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); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java index e69b8578df..79d7d250e7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java +++ b/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()); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java index e36b82f1e8..8a967395ab 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventRepository.java +++ b/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 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 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 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 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 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 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 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 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 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 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 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 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 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 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); +// } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index deb3c87402..0717fa6896 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/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 implements EventDao { +public class JpaBaseEventDao implements EventDao { private static final long PARTITION_DURATION = TimeUnit.HOURS.toMillis(1); private final Map> partitionsByEventType = new ConcurrentHashMap<>(); @@ -85,20 +78,19 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen private EventRepository eventRepository; @Autowired - private EventInsertRepository eventInsertRepository; + private LifecycleEventRepository lcEventRepository; @Autowired - private EventCleanupRepository eventCleanupRepository; + private StatisticsEventRepository statsEventRepository; - @Override - protected Class getEntityClass() { - return EventEntity.class; - } + @Autowired + private ErrorEventRepository errorEventRepository; - @Override - protected JpaRepository getRepository() { - return eventRepository; - } + @Autowired + private EventInsertRepository eventInsertRepository; + + @Autowired + private EventCleanupRepository eventCleanupRepository; @Autowired ScheduledLogExecutorComponent logExecutor; @@ -198,13 +190,6 @@ public class JpaBaseEventDao extends JpaAbstractDao 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 findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) { return null; @@ -221,22 +206,37 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen } @Override - public PageData 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 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 findLcEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { + return DaoUtil.toPageData( + lcEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); } + private PageData findStatsEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { + return DaoUtil.toPageData( + statsEventRepository.findEventsWithoutFilter(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); + } + + private PageData findErrorEventsWithoutFilter(UUID tenantId, UUID entityId, TimePageLink pageLink) { + return DaoUtil.toPageData( + errorEventRepository.findEvents(tenantId, entityId, pageLink.getStartTime(), pageLink.getEndTime(), DaoUtil.toPageable(pageLink))); + } + + @Override - public PageData findEventByFilter(UUID tenantId, EntityId entityId, EventFilter eventFilter, TimePageLink pageLink) { + public PageData 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 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 implemen // DaoUtil.toPageable(pageLink))); } - private PageData 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 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 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 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 findEventByFilter(UUID tenantId, EntityId entityId, StatisticsEventFilter eventFilter, TimePageLink pageLink) { @@ -332,7 +328,7 @@ public class JpaBaseEventDao extends JpaAbstractDao implemen } @Override - public List findLatestEvents(UUID tenantId, EntityId entityId, String eventType, int limit) { + public List findLatestEvents(UUID tenantId, UUID entityId, EventType eventType, int limit) { return null; // List latest = eventRepository.findLatestByTenantIdAndEntityTypeAndEntityIdAndEventType( // tenantId, diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/LifecycleEventRepository.java new file mode 100644 index 0000000000..f95959ad29 --- /dev/null +++ b/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 { + + @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 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 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); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/StatisticsEventRepository.java new file mode 100644 index 0000000000..2d41501933 --- /dev/null +++ b/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 { + + @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 findEventsWithoutFilter(@Param("tenantId") UUID tenantId, + @Param("entityId") UUID entityId, + @Param("startTime") Long startTime, + @Param("endTime") Long endTime, + Pageable pageable); + +} diff --git a/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql b/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql index 7e15b419a8..b8fc60ecca 100644 --- a/dao/src/main/resources/sql/schema-entities-idx-psql-addon.sql +++ b/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'; diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 9494e4bdd6..1ab89c7885 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/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, diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index 1276f46621..3c856c2c70 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/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(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java index ffd15ff5ba..eee70f6624 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java +++ b/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 events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, - timePageLink); + PageData 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 events = eventService.findEvents(tenantId, customerId, DataConstants.STATS, - timePageLink); + PageData 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); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java index 4381aab18f..16170c10ea 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java +++ b/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. */