Alarm Query performance improvements
This commit is contained in:
parent
a8dad4c6e0
commit
d3c20b2e57
29
application/src/main/data/upgrade/3.3.2/schema_update.sql
Normal file
29
application/src/main/data/upgrade/3.3.2/schema_update.sql
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
--
|
||||||
|
-- Copyright © 2016-2021 The Thingsboard Authors
|
||||||
|
--
|
||||||
|
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
-- you may not use this file except in compliance with the License.
|
||||||
|
-- You may obtain a copy of the License at
|
||||||
|
--
|
||||||
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
--
|
||||||
|
-- Unless required by applicable law or agreed to in writing, software
|
||||||
|
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
-- See the License for the specific language governing permissions and
|
||||||
|
-- limitations under the License.
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS entity_alarm (
|
||||||
|
tenant_id uuid NOT NULL,
|
||||||
|
entity_id uuid NOT NULL,
|
||||||
|
created_time bigint NOT NULL,
|
||||||
|
type varchar(255) NOT NULL,
|
||||||
|
customer_id uuid,
|
||||||
|
alarm_id uuid
|
||||||
|
CONSTRAINT entity_alarm_pkey PRIMARY KEY(entity_id, alarm_id),
|
||||||
|
CONSTRAINT fk_entity_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_status_created_time ON alarm(tenant_id, status, created_time DESC);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_entity_alarm_created_time ON entity_alarm(tenant_id, entity_id, created_time DESC);
|
||||||
@ -210,6 +210,10 @@ public class ThingsboardInstallService {
|
|||||||
log.info("Upgrading ThingsBoard from version 3.3.0 to 3.3.1 ...");
|
log.info("Upgrading ThingsBoard from version 3.3.0 to 3.3.1 ...");
|
||||||
case "3.3.1":
|
case "3.3.1":
|
||||||
log.info("Upgrading ThingsBoard from version 3.3.1 to 3.3.2 ...");
|
log.info("Upgrading ThingsBoard from version 3.3.1 to 3.3.2 ...");
|
||||||
|
break;
|
||||||
|
case "3.3.2":
|
||||||
|
log.info("Upgrading ThingsBoard from version 3.3.2 to 3.3.3 ...");
|
||||||
|
databaseEntitiesUpgradeService.upgradeDatabase("3.3.2");
|
||||||
log.info("Updating system data...");
|
log.info("Updating system data...");
|
||||||
systemDataLoaderService.updateSystemWidgets();
|
systemDataLoaderService.updateSystemWidgets();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -469,6 +469,28 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
|
|||||||
log.error("Failed updating schema!!!", e);
|
log.error("Failed updating schema!!!", e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "3.3.2":
|
||||||
|
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
|
||||||
|
log.info("Updating schema ...");
|
||||||
|
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.2", SCHEMA_UPDATE_SQL);
|
||||||
|
loadSql(schemaUpdateFile, conn);
|
||||||
|
try {
|
||||||
|
conn.createStatement().execute("insert into entity_alarm(tenant_id, entity_id, created_time, type, customer_id, alarm_id, status, severity)" +
|
||||||
|
" select tenant_id, originator_id, created_time, type, customer_id, id, status, severity from alarm;");
|
||||||
|
conn.createStatement().execute("insert into entity_alarm(tenant_id, entity_id, created_time, type, customer_id, alarm_id, status, severity)" +
|
||||||
|
" select a.tenant_id, r.from_id, created_time, type, customer_id, id, status, severity" +
|
||||||
|
" from alarm a inner join relation r on r.relation_type_group = 'ALARM' and r.relation_type = 'ANY' and a.id = r.to_id ON CONFLICT DO NOTHING;");
|
||||||
|
conn.createStatement().execute("delete from relation r where r.relation_type_group = 'ALARM';");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to update alarm relations!!!", e);
|
||||||
|
}
|
||||||
|
log.info("Updating schema settings...");
|
||||||
|
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3003003;");
|
||||||
|
log.info("Schema updated.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed updating schema!!!", e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
|
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2021 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.alarm;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.thingsboard.server.common.data.HasTenantId;
|
||||||
|
import org.thingsboard.server.common.data.id.AlarmId;
|
||||||
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EntityAlarm implements HasTenantId {
|
||||||
|
|
||||||
|
private TenantId tenantId;
|
||||||
|
private EntityId entityId;
|
||||||
|
private long createdTime;
|
||||||
|
private String alarmType;
|
||||||
|
|
||||||
|
private CustomerId customerId;
|
||||||
|
private AlarmId alarmId;
|
||||||
|
|
||||||
|
}
|
||||||
@ -18,7 +18,6 @@ package org.thingsboard.server.common.data.relation;
|
|||||||
public enum RelationTypeGroup {
|
public enum RelationTypeGroup {
|
||||||
|
|
||||||
COMMON,
|
COMMON,
|
||||||
ALARM,
|
|
||||||
DASHBOARD,
|
DASHBOARD,
|
||||||
RULE_CHAIN,
|
RULE_CHAIN,
|
||||||
RULE_NODE,
|
RULE_NODE,
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
|||||||
import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||||
|
import org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||||
import org.thingsboard.server.common.data.id.AlarmId;
|
import org.thingsboard.server.common.data.id.AlarmId;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
@ -32,6 +33,7 @@ import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
|||||||
import org.thingsboard.server.dao.Dao;
|
import org.thingsboard.server.dao.Dao;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -59,4 +61,7 @@ public interface AlarmDao extends Dao<Alarm> {
|
|||||||
|
|
||||||
PageData<AlarmId> findAlarmsIdsByEndTsBeforeAndTenantId(Long time, TenantId tenantId, PageLink pageLink);
|
PageData<AlarmId> findAlarmsIdsByEndTsBeforeAndTenantId(Long time, TenantId tenantId, PageLink pageLink);
|
||||||
|
|
||||||
|
void createEntityAlarmRecord(EntityAlarm entityAlarm);
|
||||||
|
|
||||||
|
List<EntityAlarm> findEntityAlarmRecords(TenantId tenantId, AlarmId id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
|||||||
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
|
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||||
|
import org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||||
import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededException;
|
import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededException;
|
||||||
import org.thingsboard.server.common.data.id.AlarmId;
|
import org.thingsboard.server.common.data.id.AlarmId;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
@ -166,23 +167,24 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
private AlarmOperationResult createAlarm(Alarm alarm) throws InterruptedException, ExecutionException {
|
private AlarmOperationResult createAlarm(Alarm alarm) throws InterruptedException, ExecutionException {
|
||||||
log.debug("New Alarm : {}", alarm);
|
log.debug("New Alarm : {}", alarm);
|
||||||
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
|
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
|
||||||
List<EntityId> propagatedEntitiesList = createAlarmRelations(saved);
|
List<EntityId> propagatedEntitiesList = createEntityAlarmRecords(saved);
|
||||||
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList);
|
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EntityId> createAlarmRelations(Alarm alarm) throws InterruptedException, ExecutionException {
|
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
|
||||||
List<EntityId> propagatedEntitiesList;
|
List<EntityId> propagatedEntitiesList;
|
||||||
if (alarm.isPropagate()) {
|
if (alarm.isPropagate()) {
|
||||||
Set<EntityId> parentEntities = getParentEntities(alarm);
|
Set<EntityId> parentEntities = getParentEntities(alarm);
|
||||||
propagatedEntitiesList = new ArrayList<>(parentEntities.size() + 1);
|
propagatedEntitiesList = new ArrayList<>(parentEntities.size() + 1);
|
||||||
for (EntityId parentId : parentEntities) {
|
for (EntityId parentId : parentEntities) {
|
||||||
propagatedEntitiesList.add(parentId);
|
propagatedEntitiesList.add(parentId);
|
||||||
createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId());
|
createEntityAlarmRecord(alarm.getTenantId(), parentId, alarm);
|
||||||
}
|
}
|
||||||
propagatedEntitiesList.add(alarm.getOriginator());
|
propagatedEntitiesList.add(alarm.getOriginator());
|
||||||
} else {
|
} else {
|
||||||
propagatedEntitiesList = Collections.singletonList(alarm.getOriginator());
|
propagatedEntitiesList = Collections.singletonList(alarm.getOriginator());
|
||||||
}
|
}
|
||||||
|
createEntityAlarmRecord(alarm.getTenantId(), alarm.getOriginator(), alarm);
|
||||||
return propagatedEntitiesList;
|
return propagatedEntitiesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +223,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
List<EntityId> propagatedEntitiesList;
|
List<EntityId> propagatedEntitiesList;
|
||||||
if (!oldPropagate && newPropagate) {
|
if (!oldPropagate && newPropagate) {
|
||||||
try {
|
try {
|
||||||
propagatedEntitiesList = createAlarmRelations(result);
|
propagatedEntitiesList = createEntityAlarmRecords(result);
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
log.warn("Failed to update alarm relations [{}]", result, e);
|
log.warn("Failed to update alarm relations [{}]", result, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -382,17 +384,20 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
|
|
||||||
private Set<EntityId> getPropagationEntityIds(Alarm alarm) {
|
private Set<EntityId> getPropagationEntityIds(Alarm alarm) {
|
||||||
if (alarm.isPropagate()) {
|
if (alarm.isPropagate()) {
|
||||||
List<EntityRelation> relations = relationService.findByTo(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM);
|
List<EntityAlarm> entityAlarms = alarmDao.findEntityAlarmRecords(alarm.getTenantId(), alarm.getId());
|
||||||
Set<EntityId> propagationEntityIds = relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet());
|
return entityAlarms.stream().map(EntityAlarm::getEntityId).collect(Collectors.toSet());
|
||||||
propagationEntityIds.add(alarm.getOriginator());
|
|
||||||
return propagationEntityIds;
|
|
||||||
} else {
|
} else {
|
||||||
return Collections.singleton(alarm.getOriginator());
|
return Collections.singleton(alarm.getOriginator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId) {
|
private void createEntityAlarmRecord(TenantId tenantId, EntityId entityId, Alarm alarm) {
|
||||||
createRelation(tenantId, new EntityRelation(entityId, alarmId, AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM));
|
EntityAlarm entityAlarm = new EntityAlarm(tenantId, entityId, alarm.getCreatedTime(), alarm.getType(), alarm.getCustomerId(), alarm.getId());
|
||||||
|
try {
|
||||||
|
alarmDao.createEntityAlarmRecord(entityAlarm);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[{}] Failed to create entity alarm record: {}", tenantId, entityAlarm, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> ListenableFuture<T> getAndUpdate(TenantId tenantId, AlarmId alarmId, Function<Alarm, T> function) {
|
private <T> ListenableFuture<T> getAndUpdate(TenantId tenantId, AlarmId alarmId, Function<Alarm, T> function) {
|
||||||
@ -402,7 +407,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DataValidator<Alarm> alarmDataValidator =
|
private DataValidator<Alarm> alarmDataValidator =
|
||||||
new DataValidator<Alarm>() {
|
new DataValidator<>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void validateDataImpl(TenantId tenantId, Alarm alarm) {
|
protected void validateDataImpl(TenantId tenantId, Alarm alarm) {
|
||||||
|
|||||||
@ -44,7 +44,6 @@ import org.thingsboard.server.common.data.id.EntityViewId;
|
|||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
|
|||||||
@ -257,6 +257,7 @@ public class ModelConstants {
|
|||||||
/**
|
/**
|
||||||
* Cassandra alarm constants.
|
* Cassandra alarm constants.
|
||||||
*/
|
*/
|
||||||
|
public static final String ENTITY_ALARM_COLUMN_FAMILY_NAME = "entity_alarm";
|
||||||
public static final String ALARM_COLUMN_FAMILY_NAME = "alarm";
|
public static final String ALARM_COLUMN_FAMILY_NAME = "alarm";
|
||||||
public static final String ALARM_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
|
public static final String ALARM_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
|
||||||
public static final String ALARM_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
|
public static final String ALARM_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2021 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.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||||
|
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class EntityAlarmCompositeKey implements Serializable {
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private static final long serialVersionUID = -245388185894468450L;
|
||||||
|
|
||||||
|
private UUID entityId;
|
||||||
|
private UUID alarmId;
|
||||||
|
|
||||||
|
public EntityAlarmCompositeKey(EntityAlarm entityAlarm) {
|
||||||
|
this.entityId = entityAlarm.getEntityId().getId();
|
||||||
|
this.alarmId = entityAlarm.getAlarmId().getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2021 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 org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||||
|
import org.thingsboard.server.common.data.id.AlarmId;
|
||||||
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.dao.model.ToData;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.CREATED_TIME_PROPERTY;
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_ID_PROPERTY;
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ALARM_COLUMN_FAMILY_NAME;
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ID_COLUMN;
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_COLUMN;
|
||||||
|
import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_COLUMN;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Table(name = ENTITY_ALARM_COLUMN_FAMILY_NAME)
|
||||||
|
@IdClass(EntityAlarmCompositeKey.class)
|
||||||
|
public final class EntityAlarmEntity implements ToData<EntityAlarm> {
|
||||||
|
|
||||||
|
@Column(name = TENANT_ID_COLUMN, columnDefinition = "uuid")
|
||||||
|
private UUID tenantId;
|
||||||
|
|
||||||
|
@Column(name = ENTITY_TYPE_COLUMN)
|
||||||
|
private String entityType;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = ENTITY_ID_COLUMN, columnDefinition = "uuid")
|
||||||
|
private UUID entityId;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "alarm_id", columnDefinition = "uuid")
|
||||||
|
private UUID alarmId;
|
||||||
|
|
||||||
|
@Column(name = CREATED_TIME_PROPERTY)
|
||||||
|
private long createdTime;
|
||||||
|
|
||||||
|
@Column(name = "alarm_type")
|
||||||
|
private String alarmType;
|
||||||
|
|
||||||
|
@Column(name = CUSTOMER_ID_PROPERTY, columnDefinition = "uuid")
|
||||||
|
private UUID customerId;
|
||||||
|
|
||||||
|
public EntityAlarmEntity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityAlarmEntity(EntityAlarm entityAlarm) {
|
||||||
|
tenantId = entityAlarm.getTenantId().getId();
|
||||||
|
entityId = entityAlarm.getEntityId().getId();
|
||||||
|
entityType = entityAlarm.getEntityId().getEntityType().name();
|
||||||
|
alarmId = entityAlarm.getAlarmId().getId();
|
||||||
|
alarmType = entityAlarm.getAlarmType();
|
||||||
|
createdTime = entityAlarm.getCreatedTime();
|
||||||
|
if (entityAlarm.getCustomerId() != null) {
|
||||||
|
customerId = entityAlarm.getCustomerId().getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityAlarm toData() {
|
||||||
|
EntityAlarm result = new EntityAlarm();
|
||||||
|
result.setTenantId(new TenantId(tenantId));
|
||||||
|
result.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
|
||||||
|
result.setAlarmId(new AlarmId(alarmId));
|
||||||
|
result.setAlarmType(alarmType);
|
||||||
|
result.setCreatedTime(createdTime);
|
||||||
|
if (customerId != null) {
|
||||||
|
result.setCustomerId(new CustomerId(customerId));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -42,47 +42,28 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
|
|||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
@Query(value = "SELECT new org.thingsboard.server.dao.model.sql.AlarmInfoEntity(a) FROM AlarmEntity a " +
|
@Query(value = "SELECT new org.thingsboard.server.dao.model.sql.AlarmInfoEntity(a) FROM AlarmEntity a " +
|
||||||
"LEFT JOIN RelationEntity re ON a.id = re.toId " +
|
"LEFT JOIN EntityAlarmEntity ea ON a.id = ea.alarmId " +
|
||||||
"AND re.relationTypeGroup = 'ALARM' " +
|
|
||||||
"AND re.toType = 'ALARM' " +
|
|
||||||
"AND re.fromId = :affectedEntityId " +
|
|
||||||
"AND re.fromType = :affectedEntityType " +
|
|
||||||
"WHERE a.tenantId = :tenantId " +
|
"WHERE a.tenantId = :tenantId " +
|
||||||
"AND (a.originatorId = :affectedEntityId or re.fromId IS NOT NULL) " +
|
"AND ea.tenantId = :tenantId " +
|
||||||
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
|
"AND ea.entityId = :affectedEntityId " +
|
||||||
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
|
"AND ea.entityType = :affectedEntityType " +
|
||||||
|
"AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " +
|
||||||
|
"AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " +
|
||||||
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses)) " +
|
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses)) " +
|
||||||
"AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
"AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
" OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
" OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
" OR LOWER(a.status) LIKE LOWER(CONCAT('%', :searchText, '%'))) "
|
" OR LOWER(a.status) LIKE LOWER(CONCAT('%', :searchText, '%'))) "
|
||||||
,
|
,
|
||||||
countQuery = "" +
|
countQuery = "" +
|
||||||
"SELECT count(a) + " + //alarms with relations only
|
"SELECT count(a) " + //alarms with relations only
|
||||||
" (SELECT count(a) FROM AlarmEntity a " + //alarms WITHOUT any relations
|
|
||||||
" LEFT JOIN RelationEntity re ON a.id = re.toId " +
|
|
||||||
" AND re.relationTypeGroup = 'ALARM' " +
|
|
||||||
" AND re.toType = 'ALARM' " +
|
|
||||||
" AND re.fromId = :affectedEntityId " +
|
|
||||||
" AND re.fromType = :affectedEntityType " +
|
|
||||||
" WHERE a.tenantId = :tenantId " +
|
|
||||||
" AND (a.originatorId = :affectedEntityId) " +
|
|
||||||
" AND (re.fromId IS NULL) " + //anti join
|
|
||||||
" AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
|
|
||||||
" AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
|
|
||||||
" AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses)) " +
|
|
||||||
" AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
|
||||||
" OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
|
||||||
" OR LOWER(a.status) LIKE LOWER(CONCAT('%', :searchText, '%'))) " +
|
|
||||||
" )" +
|
|
||||||
"FROM AlarmEntity a " +
|
"FROM AlarmEntity a " +
|
||||||
"INNER JOIN RelationEntity re ON a.id = re.toId " +
|
"LEFT JOIN EntityAlarmEntity ea ON a.id = ea.alarmId " +
|
||||||
"AND re.relationTypeGroup = 'ALARM' " +
|
|
||||||
"AND re.toType = 'ALARM' " +
|
|
||||||
"AND re.fromId = :affectedEntityId " +
|
|
||||||
"AND re.fromType = :affectedEntityType " +
|
|
||||||
"WHERE a.tenantId = :tenantId " +
|
"WHERE a.tenantId = :tenantId " +
|
||||||
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
|
"AND ea.tenantId = :tenantId " +
|
||||||
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
|
"AND ea.entityId = :affectedEntityId " +
|
||||||
|
"AND ea.entityType = :affectedEntityType " +
|
||||||
|
"AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " +
|
||||||
|
"AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " +
|
||||||
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses)) " +
|
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses)) " +
|
||||||
"AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
"AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
" OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
" OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
@ -149,13 +130,11 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
|
|||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
@Query(value = "SELECT a.severity FROM AlarmEntity a " +
|
@Query(value = "SELECT a.severity FROM AlarmEntity a " +
|
||||||
"LEFT JOIN RelationEntity re ON a.id = re.toId " +
|
"LEFT JOIN EntityAlarmEntity ea ON a.id = ea.alarmId " +
|
||||||
"AND re.relationTypeGroup = 'ALARM' " +
|
|
||||||
"AND re.toType = 'ALARM' " +
|
|
||||||
"AND re.fromId = :affectedEntityId " +
|
|
||||||
"AND re.fromType = :affectedEntityType " +
|
|
||||||
"WHERE a.tenantId = :tenantId " +
|
"WHERE a.tenantId = :tenantId " +
|
||||||
"AND (a.originatorId = :affectedEntityId or re.fromId IS NOT NULL) " +
|
"AND ea.tenantId = :tenantId " +
|
||||||
|
"AND ea.entityId = :affectedEntityId " +
|
||||||
|
"AND ea.entityType = :affectedEntityType " +
|
||||||
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses))")
|
"AND ((:alarmStatuses) IS NULL OR a.status in (:alarmStatuses))")
|
||||||
Set<AlarmSeverity> findAlarmSeverities(@Param("tenantId") UUID tenantId,
|
Set<AlarmSeverity> findAlarmSeverities(@Param("tenantId") UUID tenantId,
|
||||||
@Param("affectedEntityId") UUID affectedEntityId,
|
@Param("affectedEntityId") UUID affectedEntityId,
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2021 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.dao.sql.alarm;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.thingsboard.server.dao.model.sql.EntityAlarmCompositeKey;
|
||||||
|
import org.thingsboard.server.dao.model.sql.EntityAlarmEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface EntityAlarmRepository extends CrudRepository<EntityAlarmEntity, EntityAlarmCompositeKey> {
|
||||||
|
|
||||||
|
List<EntityAlarmEntity> findAllByAlarmId(UUID alarmId);
|
||||||
|
|
||||||
|
}
|
||||||
@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
|||||||
import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||||
|
import org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||||
import org.thingsboard.server.common.data.id.AlarmId;
|
import org.thingsboard.server.common.data.id.AlarmId;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
@ -37,6 +38,7 @@ import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
|||||||
import org.thingsboard.server.dao.DaoUtil;
|
import org.thingsboard.server.dao.DaoUtil;
|
||||||
import org.thingsboard.server.dao.alarm.AlarmDao;
|
import org.thingsboard.server.dao.alarm.AlarmDao;
|
||||||
import org.thingsboard.server.dao.model.sql.AlarmEntity;
|
import org.thingsboard.server.dao.model.sql.AlarmEntity;
|
||||||
|
import org.thingsboard.server.dao.model.sql.EntityAlarmEntity;
|
||||||
import org.thingsboard.server.dao.relation.RelationDao;
|
import org.thingsboard.server.dao.relation.RelationDao;
|
||||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
|
import org.thingsboard.server.dao.sql.JpaAbstractDao;
|
||||||
import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
|
import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
|
||||||
@ -62,7 +64,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
|
|||||||
private AlarmQueryRepository alarmQueryRepository;
|
private AlarmQueryRepository alarmQueryRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RelationDao relationDao;
|
private EntityAlarmRepository entityAlarmRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<AlarmEntity> getEntityClass() {
|
protected Class<AlarmEntity> getEntityClass() {
|
||||||
@ -169,4 +171,16 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
|
|||||||
return DaoUtil.pageToPageData(alarmRepository.findAlarmsIdsByEndTsBeforeAndTenantId(time, tenantId.getId(), DaoUtil.toPageable(pageLink)))
|
return DaoUtil.pageToPageData(alarmRepository.findAlarmsIdsByEndTsBeforeAndTenantId(time, tenantId.getId(), DaoUtil.toPageable(pageLink)))
|
||||||
.mapData(AlarmId::new);
|
.mapData(AlarmId::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createEntityAlarmRecord(EntityAlarm entityAlarm) {
|
||||||
|
log.debug("Saving entity {}", entityAlarm);
|
||||||
|
entityAlarmRepository.save(new EntityAlarmEntity(entityAlarm));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EntityAlarm> findEntityAlarmRecords(TenantId tenantId, AlarmId id) {
|
||||||
|
log.trace("[{}] Try to find entity alarm records using [{}]", tenantId, id);
|
||||||
|
return DaoUtil.convertDataList(entityAlarmRepository.findAllByAlarmId(id.getId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,7 +105,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
" a.propagate_relation_types as propagate_relation_types, " +
|
" a.propagate_relation_types as propagate_relation_types, " +
|
||||||
" a.type as type," + SELECT_ORIGINATOR_NAME + ", ";
|
" a.type as type," + SELECT_ORIGINATOR_NAME + ", ";
|
||||||
|
|
||||||
private static final String JOIN_RELATIONS = "left join relation r on r.relation_type_group = 'ALARM' and r.relation_type = 'ANY' and a.id = r.to_id and r.from_id in (:entity_ids)";
|
private static final String JOIN_ENTITY_ALARMS = "inner join entity_alarm ea on a.id = ea.alarm_id";
|
||||||
|
|
||||||
protected final NamedParameterJdbcTemplate jdbcTemplate;
|
protected final NamedParameterJdbcTemplate jdbcTemplate;
|
||||||
private final TransactionTemplate transactionTemplate;
|
private final TransactionTemplate transactionTemplate;
|
||||||
@ -132,8 +132,8 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
StringBuilder joinPart = new StringBuilder();
|
StringBuilder joinPart = new StringBuilder();
|
||||||
boolean addAnd = false;
|
boolean addAnd = false;
|
||||||
if (pageLink.isSearchPropagatedAlarms()) {
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
selectPart.append(" CASE WHEN r.from_id IS NULL THEN a.originator_id ELSE r.from_id END as entity_id ");
|
selectPart.append(" ea.entity_id as entity_id ");
|
||||||
fromPart.append(JOIN_RELATIONS);
|
fromPart.append(JOIN_ENTITY_ALARMS);
|
||||||
wherePart.append(buildPermissionsQuery(tenantId, customerId, ctx));
|
wherePart.append(buildPermissionsQuery(tenantId, customerId, ctx));
|
||||||
addAnd = true;
|
addAnd = true;
|
||||||
} else {
|
} else {
|
||||||
@ -145,7 +145,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
sortPart.append(alarmFieldColumnMap.getOrDefault(sortOrderKey, sortOrderKey))
|
sortPart.append(alarmFieldColumnMap.getOrDefault(sortOrderKey, sortOrderKey))
|
||||||
.append(" ").append(sortOrder.getDirection().name());
|
.append(" ").append(sortOrder.getDirection().name());
|
||||||
if (pageLink.isSearchPropagatedAlarms()) {
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
wherePart.append(" and (a.originator_id in (:entity_ids) or r.from_id IS NOT NULL)");
|
wherePart.append(" and ea.entity_id in (:entity_ids)");
|
||||||
} else {
|
} else {
|
||||||
addAndIfNeeded(wherePart, addAnd);
|
addAndIfNeeded(wherePart, addAnd);
|
||||||
addAnd = true;
|
addAnd = true;
|
||||||
@ -166,7 +166,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
}
|
}
|
||||||
joinPart.append(" as e(id, priority)) e ");
|
joinPart.append(" as e(id, priority)) e ");
|
||||||
if (pageLink.isSearchPropagatedAlarms()) {
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
joinPart.append("on (r.from_id IS NULL and a.originator_id = e.id) or (r.from_id IS NOT NULL and r.from_id = e.id)");
|
joinPart.append("on ea.entity_id = e.id");
|
||||||
} else {
|
} else {
|
||||||
joinPart.append("on a.originator_id = e.id");
|
joinPart.append("on a.originator_id = e.id");
|
||||||
}
|
}
|
||||||
@ -188,6 +188,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
addAnd = true;
|
addAnd = true;
|
||||||
ctx.addLongParameter("startTime", startTs);
|
ctx.addLongParameter("startTime", startTs);
|
||||||
wherePart.append("a.created_time >= :startTime");
|
wherePart.append("a.created_time >= :startTime");
|
||||||
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
|
wherePart.append(" and ea.created_time >= :startTime");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endTs > 0) {
|
if (endTs > 0) {
|
||||||
@ -195,6 +198,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
addAnd = true;
|
addAnd = true;
|
||||||
ctx.addLongParameter("endTime", endTs);
|
ctx.addLongParameter("endTime", endTs);
|
||||||
wherePart.append("a.created_time <= :endTime");
|
wherePart.append("a.created_time <= :endTime");
|
||||||
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
|
wherePart.append(" and ea.created_time <= :endTime");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageLink.getTypeList() != null && !pageLink.getTypeList().isEmpty()) {
|
if (pageLink.getTypeList() != null && !pageLink.getTypeList().isEmpty()) {
|
||||||
@ -202,6 +208,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
addAnd = true;
|
addAnd = true;
|
||||||
ctx.addStringListParameter("alarmTypes", pageLink.getTypeList());
|
ctx.addStringListParameter("alarmTypes", pageLink.getTypeList());
|
||||||
wherePart.append("a.type in (:alarmTypes)");
|
wherePart.append("a.type in (:alarmTypes)");
|
||||||
|
if (pageLink.isSearchPropagatedAlarms()) {
|
||||||
|
wherePart.append(" and ea.alarm_type in (:alarmTypes)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageLink.getSeverityList() != null && !pageLink.getSeverityList().isEmpty()) {
|
if (pageLink.getSeverityList() != null && !pageLink.getSeverityList().isEmpty()) {
|
||||||
@ -279,7 +288,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
|
|||||||
private String buildPermissionsQuery(TenantId tenantId, CustomerId customerId, QueryContext ctx) {
|
private String buildPermissionsQuery(TenantId tenantId, CustomerId customerId, QueryContext ctx) {
|
||||||
StringBuilder permissionsQuery = new StringBuilder();
|
StringBuilder permissionsQuery = new StringBuilder();
|
||||||
ctx.addUuidParameter("permissions_tenant_id", tenantId.getId());
|
ctx.addUuidParameter("permissions_tenant_id", tenantId.getId());
|
||||||
permissionsQuery.append(" a.tenant_id = :permissions_tenant_id ");
|
permissionsQuery.append(" a.tenant_id = :permissions_tenant_id and ea.tenant_id = :permissions_tenant_id ");
|
||||||
/*
|
/*
|
||||||
No need to check the customer id, because we already use entity id list that passed security check when we were evaluating the data query.
|
No need to check the customer id, because we already use entity id list that passed security check when we were evaluating the data query.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -33,7 +33,7 @@ public class DefaultQueryLogComponent implements QueryLogComponent {
|
|||||||
@Override
|
@Override
|
||||||
public void logQuery(QueryContext ctx, String query, long duration) {
|
public void logQuery(QueryContext ctx, String query, long duration) {
|
||||||
if (logSqlQueries && duration > logQueriesThreshold) {
|
if (logSqlQueries && duration > logQueriesThreshold) {
|
||||||
log.info("QUERY: {} took {}ms", query, duration);
|
log.info("QUERY: {} took {} ms", query, duration);
|
||||||
Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {} -> {}", param, ctx.getValue(param)));
|
Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {} -> {}", param, ctx.getValue(param)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,18 @@ CREATE TABLE IF NOT EXISTS alarm (
|
|||||||
type varchar(255)
|
type varchar(255)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS entity_alarm (
|
||||||
|
tenant_id uuid NOT NULL,
|
||||||
|
entity_type varchar(32),
|
||||||
|
entity_id uuid NOT NULL,
|
||||||
|
created_time bigint NOT NULL,
|
||||||
|
alarm_type varchar(255) NOT NULL,
|
||||||
|
customer_id uuid,
|
||||||
|
alarm_id uuid,
|
||||||
|
CONSTRAINT entity_alarm_pkey PRIMARY KEY(entity_id, alarm_id),
|
||||||
|
CONSTRAINT fk_entity_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS asset (
|
CREATE TABLE IF NOT EXISTS asset (
|
||||||
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
|
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
|
||||||
created_time bigint NOT NULL,
|
created_time bigint NOT NULL,
|
||||||
|
|||||||
@ -20,8 +20,12 @@ CREATE INDEX IF NOT EXISTS idx_alarm_originator_created_time ON alarm(originator
|
|||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_created_time ON alarm(tenant_id, created_time DESC);
|
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_created_time ON alarm(tenant_id, created_time DESC);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_status_created_time ON alarm(tenant_id, status, created_time DESC);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_created_time ON alarm(tenant_id, type, created_time DESC);
|
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_created_time ON alarm(tenant_id, type, created_time DESC);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_entity_alarm_created_time ON entity_alarm(tenant_id, entity_id, created_time DESC);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_relation_to_id ON relation(relation_type_group, to_type, to_id);
|
CREATE INDEX IF NOT EXISTS idx_relation_to_id ON relation(relation_type_group, to_type, to_id);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_relation_from_id ON relation(relation_type_group, from_type, from_id);
|
CREATE INDEX IF NOT EXISTS idx_relation_from_id ON relation(relation_type_group, from_type, from_id);
|
||||||
|
|||||||
@ -58,6 +58,18 @@ CREATE TABLE IF NOT EXISTS alarm (
|
|||||||
type varchar(255)
|
type varchar(255)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS entity_alarm (
|
||||||
|
tenant_id uuid NOT NULL,
|
||||||
|
entity_type varchar(32),
|
||||||
|
entity_id uuid NOT NULL,
|
||||||
|
created_time bigint NOT NULL,
|
||||||
|
alarm_type varchar(255) NOT NULL,
|
||||||
|
customer_id uuid,
|
||||||
|
alarm_id uuid,
|
||||||
|
CONSTRAINT entity_alarm_pkey PRIMARY KEY(entity_id, alarm_id),
|
||||||
|
CONSTRAINT fk_entity_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS asset (
|
CREATE TABLE IF NOT EXISTS asset (
|
||||||
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
|
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
|
||||||
created_time bigint NOT NULL,
|
created_time bigint NOT NULL,
|
||||||
|
|||||||
@ -612,16 +612,6 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
|
|||||||
Assert.assertEquals(1, alarms.getData().size());
|
Assert.assertEquals(1, alarms.getData().size());
|
||||||
Assert.assertEquals(created, alarms.getData().get(0));
|
Assert.assertEquals(created, alarms.getData().get(0));
|
||||||
|
|
||||||
List<EntityRelation> toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(1, toAlarmRelations.size());
|
|
||||||
|
|
||||||
List<EntityRelation> fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(0, fromChildRelations.size());
|
|
||||||
|
|
||||||
List<EntityRelation> fromParentRelations = relationService.findByFrom(tenantId, parentId, RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(1, fromParentRelations.size());
|
|
||||||
|
|
||||||
|
|
||||||
Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId()).isSuccessful());
|
Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId()).isSuccessful());
|
||||||
|
|
||||||
Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get();
|
Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get();
|
||||||
@ -647,14 +637,5 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
|
|||||||
Assert.assertNotNull(alarms.getData());
|
Assert.assertNotNull(alarms.getData());
|
||||||
Assert.assertEquals(0, alarms.getData().size());
|
Assert.assertEquals(0, alarms.getData().size());
|
||||||
|
|
||||||
toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(0, toAlarmRelations.size());
|
|
||||||
|
|
||||||
fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(0, fromChildRelations.size());
|
|
||||||
|
|
||||||
fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
|
|
||||||
Assert.assertEquals(0, fromParentRelations.size());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
DROP TABLE IF EXISTS admin_settings;
|
DROP TABLE IF EXISTS admin_settings;
|
||||||
|
DROP TABLE IF EXISTS entity_alarm;
|
||||||
DROP TABLE IF EXISTS alarm;
|
DROP TABLE IF EXISTS alarm;
|
||||||
DROP TABLE IF EXISTS asset;
|
DROP TABLE IF EXISTS asset;
|
||||||
DROP TABLE IF EXISTS audit_log;
|
DROP TABLE IF EXISTS audit_log;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
DROP TABLE IF EXISTS admin_settings;
|
DROP TABLE IF EXISTS admin_settings;
|
||||||
|
DROP TABLE IF EXISTS entity_alarm;
|
||||||
DROP TABLE IF EXISTS alarm;
|
DROP TABLE IF EXISTS alarm;
|
||||||
DROP TABLE IF EXISTS asset;
|
DROP TABLE IF EXISTS asset;
|
||||||
DROP TABLE IF EXISTS audit_log;
|
DROP TABLE IF EXISTS audit_log;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
DROP TABLE IF EXISTS admin_settings;
|
DROP TABLE IF EXISTS admin_settings;
|
||||||
|
DROP TABLE IF EXISTS entity_alarm;
|
||||||
DROP TABLE IF EXISTS alarm;
|
DROP TABLE IF EXISTS alarm;
|
||||||
DROP TABLE IF EXISTS asset;
|
DROP TABLE IF EXISTS asset;
|
||||||
DROP TABLE IF EXISTS audit_log;
|
DROP TABLE IF EXISTS audit_log;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user