Browse Source

Add customerId to alarm

pull/4563/head
Igor Kulikov 5 years ago
parent
commit
3094fb7240
  1. 5
      application/src/main/data/upgrade/3.2.2/schema_update.sql
  2. 117
      application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
  3. 16
      application/src/main/java/org/thingsboard/server/service/install/update/PaginatedUpdater.java
  4. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java
  5. 6
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java
  6. 2
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  7. 46
      dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java
  8. 1
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  9. 12
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java
  10. 5
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java
  11. 136
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  12. 9
      dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java
  13. 16
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
  14. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java
  15. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java
  16. 1
      dao/src/main/resources/sql/schema-entities-hsql.sql
  17. 1
      dao/src/main/resources/sql/schema-entities.sql
  18. 6
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html

5
application/src/main/data/upgrade/3.2.2/schema_update.sql

@ -90,6 +90,11 @@ ALTER TABLE device
ADD COLUMN IF NOT EXISTS firmware_id uuid,
ADD COLUMN IF NOT EXISTS software_id uuid;
ALTER TABLE alarm
ADD COLUMN IF NOT EXISTS customer_id uuid;
DELETE FROM relation WHERE from_type = 'TENANT' AND relation_type_group = 'RULE_CHAIN';
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN

117
application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java

@ -27,6 +27,9 @@ import org.thingsboard.rule.engine.profile.TbDeviceProfileNode;
import org.thingsboard.rule.engine.profile.TbDeviceProfileNodeConfiguration;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
@ -34,9 +37,13 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.alarm.AlarmDao;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
@ -72,6 +79,15 @@ public class DefaultDataUpdateService implements DataUpdateService {
@Autowired
private TimeseriesService tsService;
@Autowired
private AlarmService alarmService;
@Autowired
private EntityService entityService;
@Autowired
private AlarmDao alarmDao;
@Override
public void updateData(String fromVersion) throws Exception {
switch (fromVersion) {
@ -90,14 +106,25 @@ public class DefaultDataUpdateService implements DataUpdateService {
case "3.2.2":
log.info("Updating data from version 3.2.2 to 3.3.0 ...");
tenantsDefaultEdgeRuleChainUpdater.updateEntities(null);
tenantsAlarmsCustomerUpdater.updateEntities(null);
break;
default:
throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion);
}
}
private PaginatedUpdater<String, Tenant> tenantsDefaultRuleChainUpdater =
new PaginatedUpdater<String, Tenant>() {
private final PaginatedUpdater<String, Tenant> tenantsDefaultRuleChainUpdater =
new PaginatedUpdater<>() {
@Override
protected String getName() {
return "Tenants default rule chain updater";
}
@Override
protected boolean forceReportTotal() {
return true;
}
@Override
protected PageData<Tenant> findEntities(String region, PageLink pageLink) {
@ -117,8 +144,18 @@ public class DefaultDataUpdateService implements DataUpdateService {
}
};
private PaginatedUpdater<String, Tenant> tenantsDefaultEdgeRuleChainUpdater =
new PaginatedUpdater<String, Tenant>() {
private final PaginatedUpdater<String, Tenant> tenantsDefaultEdgeRuleChainUpdater =
new PaginatedUpdater<>() {
@Override
protected String getName() {
return "Tenants default edge rule chain updater";
}
@Override
protected boolean forceReportTotal() {
return true;
}
@Override
protected PageData<Tenant> findEntities(String region, PageLink pageLink) {
@ -138,8 +175,18 @@ public class DefaultDataUpdateService implements DataUpdateService {
}
};
private PaginatedUpdater<String, Tenant> tenantsRootRuleChainUpdater =
new PaginatedUpdater<String, Tenant>() {
private final PaginatedUpdater<String, Tenant> tenantsRootRuleChainUpdater =
new PaginatedUpdater<>() {
@Override
protected String getName() {
return "Tenants root rule chain updater";
}
@Override
protected boolean forceReportTotal() {
return true;
}
@Override
protected PageData<Tenant> findEntities(String region, PageLink pageLink) {
@ -192,8 +239,18 @@ public class DefaultDataUpdateService implements DataUpdateService {
}
};
private PaginatedUpdater<String, Tenant> tenantsEntityViewsUpdater =
new PaginatedUpdater<String, Tenant>() {
private final PaginatedUpdater<String, Tenant> tenantsEntityViewsUpdater =
new PaginatedUpdater<>() {
@Override
protected String getName() {
return "Tenants entity views updater";
}
@Override
protected boolean forceReportTotal() {
return true;
}
@Override
protected PageData<Tenant> findEntities(String region, PageLink pageLink) {
@ -261,4 +318,48 @@ public class DefaultDataUpdateService implements DataUpdateService {
}, MoreExecutors.directExecutor());
}
private final PaginatedUpdater<String, Tenant> tenantsAlarmsCustomerUpdater =
new PaginatedUpdater<>() {
@Override
protected String getName() {
return "Tenants alarms customer updater";
}
@Override
protected boolean forceReportTotal() {
return true;
}
@Override
protected PageData<Tenant> findEntities(String region, PageLink pageLink) {
return tenantService.findTenants(pageLink);
}
@Override
protected void updateEntity(Tenant tenant) {
updateTenantAlarmsCustomer(tenant.getId());
}
};
private void updateTenantAlarmsCustomer(TenantId tenantId) {
AlarmQuery alarmQuery = new AlarmQuery(null, new TimePageLink(100), null, null, false);
PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, alarmQuery);
boolean hasNext = true;
while (hasNext) {
for (Alarm alarm : alarms.getData()) {
if (alarm.getCustomerId() == null && alarm.getOriginator() != null) {
alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator()));
alarmDao.save(tenantId, alarm);
}
}
if (alarms.hasNext()) {
alarmQuery.setPageLink(alarmQuery.getPageLink().nextPageLink());
alarms = alarmDao.findAlarms(tenantId, alarmQuery);
} else {
hasNext = false;
}
}
}
}

16
application/src/main/java/org/thingsboard/server/service/install/update/PaginatedUpdater.java

@ -15,16 +15,20 @@
*/
package org.thingsboard.server.service.install.update;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.SearchTextBased;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@Slf4j
public abstract class PaginatedUpdater<I, D extends SearchTextBased<? extends UUIDBased>> {
private static final int DEFAULT_LIMIT = 100;
private int updated = 0;
public void updateEntities(I id) {
updated = 0;
PageLink pageLink = new PageLink(DEFAULT_LIMIT);
boolean hasNext = true;
while (hasNext) {
@ -32,13 +36,25 @@ public abstract class PaginatedUpdater<I, D extends SearchTextBased<? extends UU
for (D entity : entities.getData()) {
updateEntity(entity);
}
updated += entities.getData().size();
hasNext = entities.hasNext();
if (hasNext) {
log.info("{}: {} entities updated so far...", getName(), updated);
pageLink = pageLink.nextPageLink();
} else {
if (updated > DEFAULT_LIMIT || forceReportTotal()) {
log.info("{}: {} total entities updated.", getName(), updated);
}
}
}
}
protected boolean forceReportTotal() {
return false;
}
protected abstract String getName();
protected abstract PageData<D> findEntities(I id, PageLink pageLink);
protected abstract void updateEntity(D entity);

2
common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java

@ -28,6 +28,8 @@ public interface EntityService {
ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId);
CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId);
void deleteEntityRelations(TenantId tenantId, EntityId entityId);
long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query);

6
common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java

@ -21,9 +21,11 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.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;
@ -35,9 +37,10 @@ import java.util.List;
@Data
@Builder
@AllArgsConstructor
public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId {
public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, HasCustomerId {
private TenantId tenantId;
private CustomerId customerId;
private String type;
private EntityId originator;
private AlarmSeverity severity;
@ -62,6 +65,7 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId {
super(alarm.getId());
this.createdTime = alarm.getCreatedTime();
this.tenantId = alarm.getTenantId();
this.customerId = alarm.getCustomerId();
this.type = alarm.getType();
this.originator = alarm.getOriginator();
this.severity = alarm.getSeverity();

2
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java

@ -110,6 +110,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
if (alarm.getEndTs() == 0L) {
alarm.setEndTs(alarm.getStartTs());
}
alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()));
if (alarm.getId() == null) {
Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType()).get();
if (existing == null || existing.getStatus().isCleared()) {
@ -355,6 +356,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
existing.setStatus(alarm.getStatus());
existing.setSeverity(alarm.getSeverity());
existing.setDetails(alarm.getDetails());
existing.setCustomerId(alarm.getCustomerId());
existing.setPropagate(existing.isPropagate() || alarm.isPropagate());
List<String> existingPropagateRelationTypes = existing.getPropagateRelationTypes();
List<String> newRelationTypes = alarm.getPropagateRelationTypes();

46
dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java

@ -22,6 +22,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.AssetId;
@ -54,6 +55,7 @@ import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.service.Validator.validateId;
/**
@ -175,6 +177,50 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
return entityName;
}
@Override
public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) {
log.trace("Executing fetchEntityCustomerId [{}]", entityId);
HasCustomerId hasCustomerId = null;
switch (entityId.getEntityType()) {
case TENANT:
case RULE_CHAIN:
case RULE_NODE:
case DASHBOARD:
case WIDGETS_BUNDLE:
case WIDGET_TYPE:
case TENANT_PROFILE:
case DEVICE_PROFILE:
case API_USAGE_STATE:
case TB_RESOURCE:
case FIRMWARE:
break;
case CUSTOMER:
hasCustomerId = () -> new CustomerId(entityId.getId());
break;
case USER:
hasCustomerId = userService.findUserById(tenantId, new UserId(entityId.getId()));
break;
case ASSET:
hasCustomerId = assetService.findAssetById(tenantId, new AssetId(entityId.getId()));
break;
case DEVICE:
hasCustomerId = deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId()));
break;
case ALARM:
try {
hasCustomerId = alarmService.findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())).get();
} catch (Exception e) {}
break;
case ENTITY_VIEW:
hasCustomerId = entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId()));
break;
case EDGE:
hasCustomerId = edgeService.findEdgeById(tenantId, new EdgeId(entityId.getId()));
break;
}
return hasCustomerId != null ? hasCustomerId.getCustomerId() : new CustomerId(NULL_UUID);
}
private static void validateEntityCountQuery(EntityCountQuery query) {
if (query == null) {
throw new IncorrectParameterException("Query must be specified.");

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

@ -258,6 +258,7 @@ public class ModelConstants {
*/
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_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
public static final String ALARM_TYPE_PROPERTY = "type";
public static final String ALARM_DETAILS_PROPERTY = "details";
public static final String ALARM_ORIGINATOR_ID_PROPERTY = "originator_id";

12
dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java

@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
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.BaseEntity;
@ -44,6 +45,7 @@ import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ACK_TS_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_CLEAR_TS_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_END_TS_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY;
@ -64,6 +66,9 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
@Column(name = ALARM_TENANT_ID_PROPERTY)
private UUID tenantId;
@Column(name = ALARM_CUSTOMER_ID_PROPERTY)
private UUID customerId;
@Column(name = ALARM_ORIGINATOR_ID_PROPERTY)
private UUID originatorId;
@ -115,6 +120,9 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
if (alarm.getTenantId() != null) {
this.tenantId = alarm.getTenantId().getId();
}
if (alarm.getCustomerId() != null) {
this.customerId = alarm.getCustomerId().getId();
}
this.type = alarm.getType();
this.originatorId = alarm.getOriginator().getId();
this.originatorType = alarm.getOriginator().getEntityType();
@ -138,6 +146,7 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
this.setId(alarmEntity.getId());
this.setCreatedTime(alarmEntity.getCreatedTime());
this.tenantId = alarmEntity.getTenantId();
this.customerId = alarmEntity.getCustomerId();
this.type = alarmEntity.getType();
this.originatorId = alarmEntity.getOriginatorId();
this.originatorType = alarmEntity.getOriginatorType();
@ -159,6 +168,9 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
if (tenantId != null) {
alarm.setTenantId(new TenantId(tenantId));
}
if (customerId != null) {
alarm.setCustomerId(new CustomerId(customerId));
}
alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId));
alarm.setType(type);
alarm.setSeverity(severity);

5
dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java

@ -19,6 +19,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Entity;
@ -37,6 +38,10 @@ public final class AlarmEntity extends AbstractAlarmEntity<Alarm> {
super();
}
public AlarmEntity(AlarmInfo alarmInfo) {
super(alarmInfo);
}
public AlarmEntity(Alarm alarm) {
super(alarm);
}

136
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -100,12 +100,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Transactional
public RuleChain saveRuleChain(RuleChain ruleChain) {
ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
RuleChain savedRuleChain = ruleChainDao.save(ruleChain.getTenantId(), ruleChain);
if (ruleChain.isRoot() && ruleChain.getId() == null) {
createRelation(ruleChain.getTenantId(), new EntityRelation(savedRuleChain.getTenantId(), savedRuleChain.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
}
return savedRuleChain;
return ruleChainDao.save(ruleChain.getTenantId(), ruleChain);
}
@Override
@ -114,29 +109,20 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId());
if (!ruleChain.isRoot()) {
RuleChain previousRootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId());
try {
if (previousRootRuleChain == null) {
setRootAndSave(tenantId, ruleChain);
return true;
} else if (!previousRootRuleChain.getId().equals(ruleChain.getId())) {
deleteRelation(tenantId, new EntityRelation(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
previousRootRuleChain.setRoot(false);
ruleChainDao.save(tenantId, previousRootRuleChain);
setRootAndSave(tenantId, ruleChain);
return true;
}
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to set root rule chain, ruleChainId: [{}]", ruleChainId);
throw new RuntimeException(e);
if (previousRootRuleChain == null) {
setRootAndSave(tenantId, ruleChain);
return true;
} else if (!previousRootRuleChain.getId().equals(ruleChain.getId())) {
previousRootRuleChain.setRoot(false);
ruleChainDao.save(tenantId, previousRootRuleChain);
setRootAndSave(tenantId, ruleChain);
return true;
}
}
return false;
}
private void setRootAndSave(TenantId tenantId, RuleChain ruleChain) throws ExecutionException, InterruptedException {
createRelation(tenantId, new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
private void setRootAndSave(TenantId tenantId, RuleChain ruleChain) {
ruleChain.setRoot(true);
ruleChainDao.save(tenantId, ruleChain);
}
@ -179,41 +165,45 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
toDelete.add(existingNode);
}
}
for (RuleNode node : toAddOrUpdate) {
node.setRuleChainId(ruleChain.getId());
RuleNode savedNode = ruleNodeDao.save(tenantId, node);
createRelation(tenantId, new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
int index = nodes.indexOf(node);
nodes.set(index, savedNode);
ruleNodeIndexMap.put(savedNode.getId(), index);
if (nodes != null) {
for (RuleNode node : toAddOrUpdate) {
node.setRuleChainId(ruleChain.getId());
RuleNode savedNode = ruleNodeDao.save(tenantId, node);
createRelation(tenantId, new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
int index = nodes.indexOf(node);
nodes.set(index, savedNode);
ruleNodeIndexMap.put(savedNode.getId(), index);
}
}
for (RuleNode node : toDelete) {
deleteRuleNode(tenantId, node.getId());
}
RuleNodeId firstRuleNodeId = null;
if (ruleChainMetaData.getFirstNodeIndex() != null) {
firstRuleNodeId = nodes.get(ruleChainMetaData.getFirstNodeIndex()).getId();
}
if ((ruleChain.getFirstRuleNodeId() != null && !ruleChain.getFirstRuleNodeId().equals(firstRuleNodeId))
|| (ruleChain.getFirstRuleNodeId() == null && firstRuleNodeId != null)) {
ruleChain.setFirstRuleNodeId(firstRuleNodeId);
ruleChainDao.save(tenantId, ruleChain);
}
if (ruleChainMetaData.getConnections() != null) {
for (NodeConnectionInfo nodeConnection : ruleChainMetaData.getConnections()) {
EntityId from = nodes.get(nodeConnection.getFromIndex()).getId();
EntityId to = nodes.get(nodeConnection.getToIndex()).getId();
String type = nodeConnection.getType();
createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE));
if (nodes != null) {
if (ruleChainMetaData.getFirstNodeIndex() != null) {
firstRuleNodeId = nodes.get(ruleChainMetaData.getFirstNodeIndex()).getId();
}
}
if (ruleChainMetaData.getRuleChainConnections() != null) {
for (RuleChainConnectionInfo nodeToRuleChainConnection : ruleChainMetaData.getRuleChainConnections()) {
EntityId from = nodes.get(nodeToRuleChainConnection.getFromIndex()).getId();
EntityId to = nodeToRuleChainConnection.getTargetRuleChainId();
String type = nodeToRuleChainConnection.getType();
createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE, nodeToRuleChainConnection.getAdditionalInfo()));
if ((ruleChain.getFirstRuleNodeId() != null && !ruleChain.getFirstRuleNodeId().equals(firstRuleNodeId))
|| (ruleChain.getFirstRuleNodeId() == null && firstRuleNodeId != null)) {
ruleChain.setFirstRuleNodeId(firstRuleNodeId);
ruleChainDao.save(tenantId, ruleChain);
}
if (ruleChainMetaData.getConnections() != null) {
for (NodeConnectionInfo nodeConnection : ruleChainMetaData.getConnections()) {
EntityId from = nodes.get(nodeConnection.getFromIndex()).getId();
EntityId to = nodes.get(nodeConnection.getToIndex()).getId();
String type = nodeConnection.getType();
createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE));
}
}
if (ruleChainMetaData.getRuleChainConnections() != null) {
for (RuleChainConnectionInfo nodeToRuleChainConnection : ruleChainMetaData.getRuleChainConnections()) {
EntityId from = nodes.get(nodeToRuleChainConnection.getFromIndex()).getId();
EntityId to = nodeToRuleChainConnection.getTargetRuleChainId();
String type = nodeToRuleChainConnection.getType();
createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE, nodeToRuleChainConnection.getAdditionalInfo()));
}
}
}
@ -307,24 +297,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Override
public RuleChain getRootTenantRuleChain(TenantId tenantId) {
return getRootRuleChainByType(tenantId, RuleChainType.CORE);
}
private RuleChain getRootRuleChainByType(TenantId tenantId, RuleChainType type) {
Validator.validateId(tenantId, "Incorrect tenant id for search request.");
List<EntityRelation> relations = relationService.findByFrom(tenantId, tenantId, RelationTypeGroup.RULE_CHAIN);
if (relations != null && !relations.isEmpty()) {
for (EntityRelation relation : relations) {
RuleChainId ruleChainId = new RuleChainId(relation.getTo().getId());
RuleChain ruleChainById = findRuleChainById(tenantId, ruleChainId);
if (type.equals(ruleChainById.getType())) {
return ruleChainById;
}
}
return null;
} else {
return null;
}
return ruleChainDao.findRootRuleChainByTenantIdAndType(tenantId.getId(), RuleChainType.CORE);
}
@Override
@ -366,7 +340,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
boolean valid = true;
EntityType toType = relation.getTo().getEntityType();
if (toType == EntityType.RULE_NODE || toType == EntityType.RULE_CHAIN) {
BaseData entity;
BaseData<?> entity;
if (relation.getTo().getEntityType() == EntityType.RULE_NODE) {
entity = ruleNodeDao.findById(tenantId, relation.getTo().getId());
} else {
@ -501,9 +475,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
ObjectNode objNode = (ObjectNode) node;
objNode.put("id", tenantId.getId().toString());
} else {
Iterator<JsonNode> childIter = node.iterator();
while (childIter.hasNext()) {
searchTenantIdRecursive(tenantId, childIter.next());
for (JsonNode jsonNode : node) {
searchTenantIdRecursive(tenantId, jsonNode);
}
}
}
@ -608,7 +581,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Override
public RuleChain getEdgeTemplateRootRuleChain(TenantId tenantId) {
return getRootRuleChainByType(tenantId, RuleChainType.EDGE);
Validator.validateId(tenantId, "Incorrect tenant id for search request.");
return ruleChainDao.findRootRuleChainByTenantIdAndType(tenantId.getId(), RuleChainType.EDGE);
}
@Override
@ -618,13 +592,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
if (previousEdgeTemplateRootRuleChain == null || !previousEdgeTemplateRootRuleChain.getId().equals(ruleChain.getId())) {
try {
if (previousEdgeTemplateRootRuleChain != null) {
deleteRelation(tenantId, new EntityRelation(previousEdgeTemplateRootRuleChain.getTenantId(), previousEdgeTemplateRootRuleChain.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
previousEdgeTemplateRootRuleChain.setRoot(false);
ruleChainDao.save(tenantId, previousEdgeTemplateRootRuleChain);
}
createRelation(tenantId, new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(),
EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
ruleChain.setRoot(true);
ruleChainDao.save(tenantId, ruleChain);
return true;
@ -699,8 +669,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
ruleNodeDao.removeById(tenantId, entityId.getId());
}
private DataValidator<RuleChain> ruleChainValidator =
new DataValidator<RuleChain>() {
private final DataValidator<RuleChain> ruleChainValidator =
new DataValidator<>() {
@Override
protected void validateCreate(TenantId tenantId, RuleChain data) {
DefaultTenantProfileConfiguration profileConfiguration =
@ -739,8 +709,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
}
};
private PaginatedRemover<TenantId, RuleChain> tenantRuleChainsRemover =
new PaginatedRemover<TenantId, RuleChain>() {
private final PaginatedRemover<TenantId, RuleChain> tenantRuleChainsRemover =
new PaginatedRemover<>() {
@Override
protected PageData<RuleChain> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {

9
dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainDao.java

@ -50,6 +50,15 @@ public interface RuleChainDao extends Dao<RuleChain>, TenantEntityDao {
*/
PageData<RuleChain> findRuleChainsByTenantIdAndType(UUID tenantId, RuleChainType type, PageLink pageLink);
/**
* Find root rule chain by tenantId and type
*
* @param tenantId the tenantId
* @param type the type
* @return the rule chain object
*/
RuleChain findRootRuleChainByTenantIdAndType(UUID tenantId, RuleChainType type);
/**
* Find rule chains by tenantId, edgeId and page link.
*

16
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java

@ -120,13 +120,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
Pageable pageable);
@Query(value = "SELECT new org.thingsboard.server.dao.model.sql.AlarmInfoEntity(a) FROM AlarmEntity a " +
"WHERE a.tenantId = :tenantId " +
"AND (" +
"a.originatorId IN (SELECT d.id from DeviceEntity d WHERE d.customerId = :customerId) " +
"OR a.originatorId IN (SELECT asset.id from AssetEntity asset WHERE asset.customerId = :customerId) " +
"OR a.originatorId IN (SELECT u.id from UserEntity u WHERE u.customerId = :customerId) " +
"OR a.originatorId = :customerId" +
") " +
"WHERE a.tenantId = :tenantId AND a.customerId = :customerId " +
"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)) " +
@ -137,13 +131,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
countQuery = "" +
"SELECT count(a) " +
"FROM AlarmEntity a " +
"WHERE a.tenantId = :tenantId " +
"AND (" +
"a.originatorId IN (SELECT d.id from DeviceEntity d WHERE d.customerId = :customerId) " +
"OR a.originatorId IN (SELECT asset.id from AssetEntity asset WHERE asset.customerId = :customerId) " +
"OR a.originatorId IN (SELECT u.id from UserEntity u WHERE u.customerId = :customerId) " +
"OR a.originatorId = :customerId" +
") " +
"WHERE a.tenantId = :tenantId AND a.customerId = :customerId " +
"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)) " +

6
dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java

@ -82,6 +82,12 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
DaoUtil.toPageable(pageLink)));
}
@Override
public RuleChain findRootRuleChainByTenantIdAndType(UUID tenantId, RuleChainType type) {
log.debug("Try to find root rule chain by tenantId [{}] and type [{}]", tenantId, type);
return DaoUtil.getData(ruleChainRepository.findByTenantIdAndTypeAndRootIsTrue(tenantId, type));
}
@Override
public PageData<RuleChain> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, PageLink pageLink) {
log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);

3
dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleChainRepository.java

@ -50,5 +50,8 @@ public interface RuleChainRepository extends PagingAndSortingRepository<RuleChai
@Param("edgeId") UUID edgeId,
@Param("searchText") String searchText,
Pageable pageable);
RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType);
Long countByTenantId(UUID tenantId);
}

1
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS alarm (
start_ts bigint,
status varchar(255),
tenant_id uuid,
customer_id uuid,
propagate_relation_types varchar,
type varchar(255)
);

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

@ -53,6 +53,7 @@ CREATE TABLE IF NOT EXISTS alarm (
start_ts bigint,
status varchar(255),
tenant_id uuid,
customer_id uuid,
propagate_relation_types varchar,
type varchar(255)
);

6
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html

@ -188,12 +188,12 @@
</mat-drawer-content>
</mat-drawer-container>
<section fxLayout="row" class="layout-wrap tb-footer-buttons" fxLayoutAlign="start end">
<tb-footer-fab-buttons *ngIf="!embedded"
<tb-footer-fab-buttons *ngIf="!embedded && !isMobileApp"
[fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
relative
[footerFabButtons]="addWidgetFabButtons">
</tb-footer-fab-buttons>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen && !embedded"
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen && !embedded && !isMobileApp"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': !isEdit || isAddingWidget}"
[disabled]="isLoading$ | async"
@ -202,7 +202,7 @@
matTooltipPosition="above">
<mat-icon>done</mat-icon>
</button>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen && !embedded"
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen && !embedded && !isMobileApp"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': isAddingWidget || (isLoading$ | async)}"
[disabled]="isLoading$ | async"

Loading…
Cancel
Save