Browse Source

Merge pull request #5921 from thingsboard/feature/propagate-to-owner

Propagate alarms to Customer or Tenant without relations
pull/5932/head
Andrew Shvayka 5 years ago
committed by GitHub
parent
commit
35d8c7b144
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java
  2. 56
      application/src/main/java/org/thingsboard/server/service/install/HsqlEntityDatabaseSchemaService.java
  3. 32
      application/src/main/java/org/thingsboard/server/service/install/HsqlTsDatabaseSchemaService.java
  4. 6
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  5. 3
      application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
  6. 2
      application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java
  7. 4
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java
  8. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java
  9. 8
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java
  10. 2
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java
  11. 8
      common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java
  12. 2
      common/edge-api/src/main/proto/edge.proto
  13. 3
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
  14. 45
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  15. 2
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  16. 14
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java
  17. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
  18. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java
  19. 2
      dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmQueryRepository.java
  20. 11
      dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java
  21. 599
      dao/src/main/resources/sql/schema-entities-hsql.sql
  22. 4
      dao/src/main/resources/sql/schema-entities.sql
  23. 41
      dao/src/main/resources/sql/schema-ts-hsql.sql
  24. 20
      dao/src/main/resources/sql/schema-types-hsql.sql
  25. 78
      dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java
  26. 2
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java
  27. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java
  28. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java
  29. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java

4
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java

@ -71,7 +71,9 @@ public class AlarmMsgConstructor {
.setAckTs(alarm.getAckTs()) .setAckTs(alarm.getAckTs())
.setClearTs(alarm.getClearTs()) .setClearTs(alarm.getClearTs())
.setDetails(JacksonUtil.toString(alarm.getDetails())) .setDetails(JacksonUtil.toString(alarm.getDetails()))
.setPropagate(alarm.isPropagate()); .setPropagate(alarm.isPropagate())
.setPropagateToOwner(alarm.isPropagateToOwner())
.setPropagateToTenant(alarm.isPropagateToTenant());
return builder.build(); return builder.build();
} }

56
application/src/main/java/org/thingsboard/server/service/install/HsqlEntityDatabaseSchemaService.java

@ -1,56 +0,0 @@
/**
* 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.service.install;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.dao.util.HsqlDao;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
@Service
@Slf4j
@HsqlDao
@Profile("install")
public class HsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
implements EntityDatabaseSchemaService {
protected HsqlEntityDatabaseSchemaService() {
super("schema-entities-hsql.sql", "schema-entities-idx.sql");
}
private final String schemaTypesSql = "schema-types-hsql.sql";
@Override
public void createDatabaseSchema(boolean createIndexes) throws Exception {
log.info("Installing SQL DataBase types part: " + schemaTypesSql);
Path schemaFile = Paths.get(installScripts.getDataDir(), SQL_DIR, schemaTypesSql);
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8"));
conn.createStatement().execute(sql); //NOSONAR, ignoring because method used to load initial thingsboard database schema
}
super.createDatabaseSchema(createIndexes);
}
}

32
application/src/main/java/org/thingsboard/server/service/install/HsqlTsDatabaseSchemaService.java

@ -1,32 +0,0 @@
/**
* 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.service.install;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.dao.util.HsqlDao;
import org.thingsboard.server.dao.util.SqlTsDao;
@Service
@SqlTsDao
@HsqlDao
@Profile("install")
public class HsqlTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService
implements TsDatabaseSchemaService {
public HsqlTsDatabaseSchemaService() {
super("schema-ts-hsql.sql", null);
}
}

6
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -475,6 +475,12 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
log.info("Updating schema ..."); log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.2", SCHEMA_UPDATE_SQL); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.2", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn); loadSql(schemaUpdateFile, conn);
try {
conn.createStatement().execute("ALTER TABLE alarm ADD COLUMN propagate_to_owner boolean DEFAULT false;"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
conn.createStatement().execute("ALTER TABLE alarm ADD COLUMN propagate_to_tenant boolean DEFAULT false;"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
} catch (Exception ignored) {
}
try { try {
conn.createStatement().execute("insert into entity_alarm(tenant_id, entity_id, created_time, alarm_type, customer_id, alarm_id)" + conn.createStatement().execute("insert into entity_alarm(tenant_id, entity_id, created_time, alarm_type, customer_id, alarm_id)" +
" select tenant_id, originator_id, created_time, type, customer_id, id from alarm ON CONFLICT DO NOTHING;"); " select tenant_id, originator_id, created_time, type, customer_id, id from alarm ON CONFLICT DO NOTHING;");

3
application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java

@ -106,8 +106,7 @@ public class DefaultEntityQueryService implements EntityQueryService {
for (EntityData entityData : entities.getData()) { for (EntityData entityData : entities.getData()) {
entitiesMap.put(entityData.getEntityId(), entityData); entitiesMap.put(entityData.getEntityId(), entityData);
} }
PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(securityUser.getTenantId(), PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(securityUser.getTenantId(), query, entitiesMap.keySet());
securityUser.getCustomerId(), query, entitiesMap.keySet());
for (AlarmData alarmData : alarms.getData()) { for (AlarmData alarmData : alarms.getData()) {
EntityId entityId = alarmData.getEntityId(); EntityId entityId = alarmData.getEntityId();
if (entityId != null) { if (entityId != null) {

2
application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java

@ -106,7 +106,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
AlarmDataUpdate update; AlarmDataUpdate update;
if (!entitiesMap.isEmpty()) { if (!entitiesMap.isEmpty()) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(getTenantId(), getCustomerId(), query, getOrderedEntityIds()); PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(getTenantId(), query, getOrderedEntityIds());
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
stats.getAlarmQueryInvocationCnt().incrementAndGet(); stats.getAlarmQueryInvocationCnt().incrementAndGet();
stats.getAlarmQueryTimeSpent().addAndGet(end - start); stats.getAlarmQueryTimeSpent().addAndGet(end - start);

4
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java

@ -150,8 +150,8 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
} }
@Override @Override
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) { public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
return alarmService.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds); return alarmService.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
} }
@Override @Override

2
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java

@ -61,7 +61,7 @@ public interface AlarmService {
ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
AlarmDataQuery query, Collection<EntityId> orderedEntityIds); AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId); void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId);

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

@ -70,7 +70,11 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha
private transient JsonNode details; private transient JsonNode details;
@ApiModelProperty(position = 15, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") @ApiModelProperty(position = 15, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true")
private boolean propagate; private boolean propagate;
@ApiModelProperty(position = 16, value = "JSON array of relation types that should be used for propagation. " + @ApiModelProperty(position = 16, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true")
private boolean propagateToOwner;
@ApiModelProperty(position = 17, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true")
private boolean propagateToTenant;
@ApiModelProperty(position = 18, value = "JSON array of relation types that should be used for propagation. " +
"By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " +
"This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.")
private List<String> propagateRelationTypes; private List<String> propagateRelationTypes;
@ -98,6 +102,8 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha
this.clearTs = alarm.getClearTs(); this.clearTs = alarm.getClearTs();
this.details = alarm.getDetails(); this.details = alarm.getDetails();
this.propagate = alarm.isPropagate(); this.propagate = alarm.isPropagate();
this.propagateToOwner = alarm.isPropagateToOwner();
this.propagateToTenant = alarm.isPropagateToTenant();
this.propagateRelationTypes = alarm.getPropagateRelationTypes(); this.propagateRelationTypes = alarm.getPropagateRelationTypes();
} }

2
common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java

@ -23,7 +23,7 @@ public class AlarmInfo extends Alarm {
private static final long serialVersionUID = 2807343093519543363L; private static final long serialVersionUID = 2807343093519543363L;
@ApiModelProperty(position = 17, value = "Alarm originator name", example = "Thermostat") @ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat")
private String originatorName; private String originatorName;
public AlarmInfo() { public AlarmInfo() {

8
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java

@ -49,8 +49,14 @@ public class DeviceProfileAlarm implements Serializable {
// Hidden in advanced settings // Hidden in advanced settings
@ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") @ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true")
private boolean propagate; private boolean propagate;
@ApiModelProperty(position = 6, value = "JSON array of relation types that should be used for propagation. " + @ApiModelProperty(position = 6, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true")
private boolean propagateToOwner;
@ApiModelProperty(position = 7, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true")
private boolean propagateToTenant;
@ApiModelProperty(position = 8, value = "JSON array of relation types that should be used for propagation. " +
"By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " +
"This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.")
private List<String> propagateRelationTypes; private List<String> propagateRelationTypes;
} }

2
common/edge-api/src/main/proto/edge.proto

@ -269,6 +269,8 @@ message AlarmUpdateMsg {
int64 clearTs = 13; int64 clearTs = 13;
string details = 14; string details = 14;
bool propagate = 15; bool propagate = 15;
bool propagateToOwner = 16;
bool propagateToTenant = 17;
} }
message CustomerUpdateMsg { message CustomerUpdateMsg {

3
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java

@ -54,8 +54,7 @@ public interface AlarmDao extends Dao<Alarm> {
PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query); PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status); Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status);

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

@ -59,6 +59,7 @@ import javax.annotation.PreDestroy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -139,11 +140,10 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} }
@Override @Override
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
AlarmDataQuery query, Collection<EntityId> orderedEntityIds) { AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); return alarmDao.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
return alarmDao.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
} }
@Override @Override
@ -171,25 +171,25 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} }
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException { private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
List<EntityId> propagatedEntitiesList; Set<EntityId> propagatedEntitiesSet = new LinkedHashSet<>();
propagatedEntitiesSet.add(alarm.getOriginator());
if (alarm.isPropagate()) { if (alarm.isPropagate()) {
Set<EntityId> parentEntities = getParentEntities(alarm); propagatedEntitiesSet.addAll(getRelatedEntities(alarm));
propagatedEntitiesList = new ArrayList<>(parentEntities.size() + 1); }
for (EntityId parentId : parentEntities) { if (alarm.isPropagateToOwner()) {
propagatedEntitiesList.add(parentId); propagatedEntitiesSet.add(alarm.getCustomerId() != null ? alarm.getCustomerId() : alarm.getTenantId());
createEntityAlarmRecord(alarm.getTenantId(), parentId, alarm);
}
propagatedEntitiesList.add(alarm.getOriginator());
} else {
propagatedEntitiesList = Collections.singletonList(alarm.getOriginator());
} }
createEntityAlarmRecord(alarm.getTenantId(), alarm.getOriginator(), alarm); if (alarm.isPropagateToTenant()) {
return propagatedEntitiesList; propagatedEntitiesSet.add(alarm.getTenantId());
}
for (EntityId entityId : propagatedEntitiesSet) {
createEntityAlarmRecord(alarm.getTenantId(), entityId, alarm);
}
return new ArrayList<>(propagatedEntitiesSet);
} }
private Set<EntityId> getParentEntities(Alarm alarm) throws InterruptedException, ExecutionException { private Set<EntityId> getRelatedEntities(Alarm alarm) throws InterruptedException, ExecutionException {
EntityRelationsQuery query = new EntityRelationsQuery(); EntityRelationsQuery query = new EntityRelationsQuery();
//TODO 3.1: @dlandiak we need to fetch max 3 levels and then fetch more if needed and there is at least one non-duplicate.
RelationsSearchParameters parameters = new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE, false); RelationsSearchParameters parameters = new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE, false);
query.setParameters(parameters); query.setParameters(parameters);
List<String> propagateRelationTypes = alarm.getPropagateRelationTypes(); List<String> propagateRelationTypes = alarm.getPropagateRelationTypes();
@ -216,11 +216,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} }
private AlarmOperationResult updateAlarm(Alarm oldAlarm, Alarm newAlarm) { private AlarmOperationResult updateAlarm(Alarm oldAlarm, Alarm newAlarm) {
boolean oldPropagate = oldAlarm.isPropagate(); boolean propagationEnabled = !oldAlarm.isPropagate() && newAlarm.isPropagate();
boolean newPropagate = newAlarm.isPropagate(); boolean propagationToOwnerEnabled = !oldAlarm.isPropagateToOwner() && newAlarm.isPropagateToOwner();
boolean propagationToTenantEnabled = !oldAlarm.isPropagateToTenant() && newAlarm.isPropagateToTenant();
Alarm result = alarmDao.save(newAlarm.getTenantId(), merge(oldAlarm, newAlarm)); Alarm result = alarmDao.save(newAlarm.getTenantId(), merge(oldAlarm, newAlarm));
List<EntityId> propagatedEntitiesList; List<EntityId> propagatedEntitiesList;
if (!oldPropagate && newPropagate) { if (propagationEnabled || propagationToOwnerEnabled || propagationToTenantEnabled) {
try { try {
propagatedEntitiesList = createEntityAlarmRecords(result); propagatedEntitiesList = createEntityAlarmRecords(result);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
@ -372,6 +373,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
existing.setDetails(alarm.getDetails()); existing.setDetails(alarm.getDetails());
existing.setCustomerId(alarm.getCustomerId()); existing.setCustomerId(alarm.getCustomerId());
existing.setPropagate(existing.isPropagate() || alarm.isPropagate()); existing.setPropagate(existing.isPropagate() || alarm.isPropagate());
existing.setPropagateToOwner(existing.isPropagateToOwner() || alarm.isPropagateToOwner());
existing.setPropagateToTenant(existing.isPropagateToTenant() || alarm.isPropagateToTenant());
List<String> existingPropagateRelationTypes = existing.getPropagateRelationTypes(); List<String> existingPropagateRelationTypes = existing.getPropagateRelationTypes();
List<String> newRelationTypes = alarm.getPropagateRelationTypes(); List<String> newRelationTypes = alarm.getPropagateRelationTypes();
if (!CollectionUtils.isEmpty(newRelationTypes)) { if (!CollectionUtils.isEmpty(newRelationTypes)) {
@ -387,7 +390,7 @@ 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() || alarm.isPropagateToOwner() || alarm.isPropagateToTenant()) {
List<EntityAlarm> entityAlarms = alarmDao.findEntityAlarmRecords(alarm.getTenantId(), alarm.getId()); List<EntityAlarm> entityAlarms = alarmDao.findEntityAlarmRecords(alarm.getTenantId(), alarm.getId());
return entityAlarms.stream().map(EntityAlarm::getEntityId).collect(Collectors.toSet()); return entityAlarms.stream().map(EntityAlarm::getEntityId).collect(Collectors.toSet());
} else { } else {

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

@ -273,6 +273,8 @@ public class ModelConstants {
public static final String ALARM_ACK_TS_PROPERTY = "ack_ts"; public static final String ALARM_ACK_TS_PROPERTY = "ack_ts";
public static final String ALARM_CLEAR_TS_PROPERTY = "clear_ts"; public static final String ALARM_CLEAR_TS_PROPERTY = "clear_ts";
public static final String ALARM_PROPAGATE_PROPERTY = "propagate"; public static final String ALARM_PROPAGATE_PROPERTY = "propagate";
public static final String ALARM_PROPAGATE_TO_OWNER_PROPERTY = "propagate_to_owner";
public static final String ALARM_PROPAGATE_TO_TENANT_PROPERTY = "propagate_to_tenant";
public static final String ALARM_PROPAGATE_RELATION_TYPES = "propagate_relation_types"; public static final String ALARM_PROPAGATE_RELATION_TYPES = "propagate_relation_types";
public static final String ALARM_BY_ID_VIEW_NAME = "alarm_by_id"; public static final String ALARM_BY_ID_VIEW_NAME = "alarm_by_id";

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

@ -51,6 +51,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ORIGINATOR_I
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_RELATION_TYPES; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_RELATION_TYPES;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_TO_OWNER_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_PROPAGATE_TO_TENANT_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_SEVERITY_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_SEVERITY_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_START_TS_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_START_TS_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ALARM_STATUS_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_STATUS_PROPERTY;
@ -105,6 +107,12 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
@Column(name = ALARM_PROPAGATE_PROPERTY) @Column(name = ALARM_PROPAGATE_PROPERTY)
private Boolean propagate; private Boolean propagate;
@Column(name = ALARM_PROPAGATE_TO_OWNER_PROPERTY)
private Boolean propagateToOwner;
@Column(name = ALARM_PROPAGATE_TO_TENANT_PROPERTY)
private Boolean propagateToTenant;
@Column(name = ALARM_PROPAGATE_RELATION_TYPES) @Column(name = ALARM_PROPAGATE_RELATION_TYPES)
private String propagateRelationTypes; private String propagateRelationTypes;
@ -130,6 +138,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
this.severity = alarm.getSeverity(); this.severity = alarm.getSeverity();
this.status = alarm.getStatus(); this.status = alarm.getStatus();
this.propagate = alarm.isPropagate(); this.propagate = alarm.isPropagate();
this.propagateToOwner = alarm.isPropagateToOwner();
this.propagateToTenant = alarm.isPropagateToTenant();
this.startTs = alarm.getStartTs(); this.startTs = alarm.getStartTs();
this.endTs = alarm.getEndTs(); this.endTs = alarm.getEndTs();
this.ackTs = alarm.getAckTs(); this.ackTs = alarm.getAckTs();
@ -154,6 +164,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
this.severity = alarmEntity.getSeverity(); this.severity = alarmEntity.getSeverity();
this.status = alarmEntity.getStatus(); this.status = alarmEntity.getStatus();
this.propagate = alarmEntity.getPropagate(); this.propagate = alarmEntity.getPropagate();
this.propagateToOwner = alarmEntity.getPropagateToOwner();
this.propagateToTenant = alarmEntity.getPropagateToTenant();
this.startTs = alarmEntity.getStartTs(); this.startTs = alarmEntity.getStartTs();
this.endTs = alarmEntity.getEndTs(); this.endTs = alarmEntity.getEndTs();
this.ackTs = alarmEntity.getAckTs(); this.ackTs = alarmEntity.getAckTs();
@ -176,6 +188,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
alarm.setSeverity(severity); alarm.setSeverity(severity);
alarm.setStatus(status); alarm.setStatus(status);
alarm.setPropagate(propagate); alarm.setPropagate(propagate);
alarm.setPropagateToOwner(propagateToOwner);
alarm.setPropagateToTenant(propagateToTenant);
alarm.setStartTs(startTs); alarm.setStartTs(startTs);
alarm.setEndTs(endTs); alarm.setEndTs(endTs);
alarm.setAckTs(ackTs); alarm.setAckTs(ackTs);

4
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java

@ -157,8 +157,8 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
} }
@Override @Override
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) { public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds); return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
} }
@Override @Override

2
dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmDataAdapter.java

@ -83,6 +83,8 @@ public class AlarmDataAdapter {
UUID originatorId = (UUID) row.get(ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY); UUID originatorId = (UUID) row.get(ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY);
alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId)); alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId));
alarm.setPropagate((boolean) row.get(ModelConstants.ALARM_PROPAGATE_PROPERTY)); alarm.setPropagate((boolean) row.get(ModelConstants.ALARM_PROPAGATE_PROPERTY));
alarm.setPropagateToOwner((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_OWNER_PROPERTY));
alarm.setPropagateToTenant((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_TENANT_PROPERTY));
alarm.setType(row.get(ModelConstants.ALARM_TYPE_PROPERTY).toString()); alarm.setType(row.get(ModelConstants.ALARM_TYPE_PROPERTY).toString());
alarm.setSeverity(AlarmSeverity.valueOf(row.get(ModelConstants.ALARM_SEVERITY_PROPERTY).toString())); alarm.setSeverity(AlarmSeverity.valueOf(row.get(ModelConstants.ALARM_SEVERITY_PROPERTY).toString()));
alarm.setStatus(AlarmStatus.valueOf(row.get(ModelConstants.ALARM_STATUS_PROPERTY).toString())); alarm.setStatus(AlarmStatus.valueOf(row.get(ModelConstants.ALARM_STATUS_PROPERTY).toString()));

2
dao/src/main/java/org/thingsboard/server/dao/sql/query/AlarmQueryRepository.java

@ -27,7 +27,7 @@ import java.util.Collection;
public interface AlarmQueryRepository { public interface AlarmQueryRepository {
PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
AlarmDataQuery query, Collection<EntityId> orderedEntityIds); AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
} }

11
dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java

@ -97,6 +97,8 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
" a.originator_id as originator_id," + " a.originator_id as originator_id," +
" a.originator_type as originator_type," + " a.originator_type as originator_type," +
" a.propagate as propagate," + " a.propagate as propagate," +
" a.propagate_to_owner as propagate_to_owner," +
" a.propagate_to_tenant as propagate_to_tenant," +
" a.severity as severity," + " a.severity as severity," +
" a.start_ts as start_ts," + " a.start_ts as start_ts," +
" a.status as status, " + " a.status as status, " +
@ -119,11 +121,10 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
} }
@Override @Override
public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
return transactionTemplate.execute(status -> { return transactionTemplate.execute(status -> {
AlarmDataPageLink pageLink = query.getPageLink(); AlarmDataPageLink pageLink = query.getPageLink();
QueryContext ctx = new QueryContext(new QuerySecurityContext(tenantId, customerId, EntityType.ALARM)); QueryContext ctx = new QueryContext(new QuerySecurityContext(tenantId, null, EntityType.ALARM));
ctx.addUuidListParameter("entity_ids", orderedEntityIds.stream().map(EntityId::getId).collect(Collectors.toList())); ctx.addUuidListParameter("entity_ids", orderedEntityIds.stream().map(EntityId::getId).collect(Collectors.toList()));
StringBuilder selectPart = new StringBuilder(FIELDS_SELECTION); StringBuilder selectPart = new StringBuilder(FIELDS_SELECTION);
StringBuilder fromPart = new StringBuilder(" from alarm a "); StringBuilder fromPart = new StringBuilder(" from alarm a ");
@ -134,7 +135,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
if (pageLink.isSearchPropagatedAlarms()) { if (pageLink.isSearchPropagatedAlarms()) {
selectPart.append(" ea.entity_id as entity_id "); selectPart.append(" ea.entity_id as entity_id ");
fromPart.append(JOIN_ENTITY_ALARMS); fromPart.append(JOIN_ENTITY_ALARMS);
wherePart.append(buildPermissionsQuery(tenantId, customerId, ctx)); wherePart.append(buildPermissionsQuery(tenantId, ctx));
addAnd = true; addAnd = true;
} else { } else {
selectPart.append(" a.originator_id as entity_id "); selectPart.append(" a.originator_id as entity_id ");
@ -285,7 +286,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
} }
} }
private String buildPermissionsQuery(TenantId tenantId, CustomerId customerId, QueryContext ctx) { private String buildPermissionsQuery(TenantId tenantId, 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 and ea.tenant_id = :permissions_tenant_id "); permissionsQuery.append(" a.tenant_id = :permissions_tenant_id and ea.tenant_id = :permissions_tenant_id ");

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

@ -1,599 +0,0 @@
--
-- 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.
--
SET DATABASE SQL SYNTAX PGS TRUE;
SET DATABASE TRANSACTION CONTROL MVCC;
CREATE TABLE IF NOT EXISTS admin_settings (
id uuid NOT NULL CONSTRAINT admin_settings_pkey PRIMARY KEY,
created_time bigint NOT NULL,
json_value varchar,
key varchar(255)
);
CREATE TABLE IF NOT EXISTS alarm (
id uuid NOT NULL CONSTRAINT alarm_pkey PRIMARY KEY,
created_time bigint NOT NULL,
ack_ts bigint,
clear_ts bigint,
additional_info varchar,
end_ts bigint,
originator_id uuid,
originator_type integer,
propagate boolean,
severity varchar(255),
start_ts bigint,
status varchar(255),
tenant_id uuid,
customer_id uuid,
propagate_relation_types varchar,
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 (
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
customer_id uuid,
name varchar(255),
label varchar(255),
search_text varchar(255),
tenant_id uuid,
type varchar(255),
CONSTRAINT asset_name_unq_key UNIQUE (tenant_id, name)
);
CREATE TABLE IF NOT EXISTS audit_log (
id uuid NOT NULL CONSTRAINT audit_log_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid,
customer_id uuid,
entity_id uuid,
entity_type varchar(255),
entity_name varchar(255),
user_id uuid,
user_name varchar(255),
action_type varchar(255),
action_data varchar(1000000),
action_status varchar(255),
action_failure_details varchar(1000000)
);
CREATE TABLE IF NOT EXISTS attribute_kv (
entity_type varchar(255),
entity_id uuid,
attribute_type varchar(255),
attribute_key varchar(255),
bool_v boolean,
str_v varchar(10000000),
long_v bigint,
dbl_v double precision,
json_v varchar(10000000),
last_update_ts bigint,
CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_type, entity_id, attribute_type, attribute_key)
);
CREATE TABLE IF NOT EXISTS component_descriptor (
id uuid NOT NULL CONSTRAINT component_descriptor_pkey PRIMARY KEY,
created_time bigint NOT NULL,
actions varchar(255),
clazz varchar UNIQUE,
configuration_descriptor varchar,
name varchar(255),
scope varchar(255),
search_text varchar(255),
type varchar(255)
);
CREATE TABLE IF NOT EXISTS customer (
id uuid NOT NULL CONSTRAINT customer_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
address varchar,
address2 varchar,
city varchar(255),
country varchar(255),
email varchar(255),
phone varchar(255),
search_text varchar(255),
state varchar(255),
tenant_id uuid,
title varchar(255),
zip varchar(255)
);
CREATE TABLE IF NOT EXISTS dashboard (
id uuid NOT NULL CONSTRAINT dashboard_pkey PRIMARY KEY,
created_time bigint NOT NULL,
configuration varchar(10000000),
assigned_customers varchar(1000000),
search_text varchar(255),
tenant_id uuid,
title varchar(255),
mobile_hide boolean DEFAULT false,
mobile_order int,
image varchar(1000000)
);
CREATE TABLE IF NOT EXISTS rule_chain (
id uuid NOT NULL CONSTRAINT rule_chain_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
configuration varchar(10000000),
name varchar(255),
type varchar(255),
first_rule_node_id uuid,
root boolean,
debug_mode boolean,
search_text varchar(255),
tenant_id uuid
);
CREATE TABLE IF NOT EXISTS rule_node (
id uuid NOT NULL CONSTRAINT rule_node_pkey PRIMARY KEY,
created_time bigint NOT NULL,
rule_chain_id uuid,
additional_info varchar,
configuration varchar(10000000),
type varchar(255),
name varchar(255),
debug_mode boolean,
search_text varchar(255)
);
CREATE TABLE IF NOT EXISTS rule_node_state (
id uuid NOT NULL CONSTRAINT rule_node_state_pkey PRIMARY KEY,
created_time bigint NOT NULL,
rule_node_id uuid NOT NULL,
entity_type varchar(32) NOT NULL,
entity_id uuid NOT NULL,
state_data varchar(16384) NOT NULL,
CONSTRAINT rule_node_state_unq_key UNIQUE (rule_node_id, entity_id),
CONSTRAINT fk_rule_node_state_node_id FOREIGN KEY (rule_node_id) REFERENCES rule_node(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS ota_package (
id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_profile_id uuid ,
type varchar(32) NOT NULL,
title varchar(255) NOT NULL,
version varchar(255) NOT NULL,
tag varchar(255),
url varchar(255),
file_name varchar(255),
content_type varchar(255),
checksum_algorithm varchar(32),
checksum varchar(1020),
data binary,
data_size bigint,
additional_info varchar,
search_text varchar(255),
CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version)
);
CREATE TABLE IF NOT EXISTS device_profile (
id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
type varchar(255),
image varchar(1000000),
transport_type varchar(255),
provision_type varchar(255),
profile_data jsonb,
description varchar,
search_text varchar(255),
is_default boolean,
tenant_id uuid,
firmware_id uuid,
software_id uuid,
default_rule_chain_id uuid,
default_dashboard_id uuid,
default_queue_name varchar(255),
provision_device_key varchar,
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES ota_package(id),
CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES ota_package(id)
);
CREATE TABLE IF NOT EXISTS device (
id uuid NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
customer_id uuid,
device_profile_id uuid NOT NULL,
device_data jsonb,
type varchar(255),
name varchar(255),
label varchar(255),
search_text varchar(255),
tenant_id uuid,
firmware_id uuid,
software_id uuid,
CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name),
CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id),
CONSTRAINT fk_firmware_device FOREIGN KEY (firmware_id) REFERENCES ota_package(id),
CONSTRAINT fk_software_device FOREIGN KEY (software_id) REFERENCES ota_package(id)
);
CREATE TABLE IF NOT EXISTS device_credentials (
id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY,
created_time bigint NOT NULL,
credentials_id varchar,
credentials_type varchar(255),
credentials_value varchar,
device_id uuid,
CONSTRAINT device_credentials_id_unq_key UNIQUE (credentials_id),
CONSTRAINT device_credentials_device_id_unq_key UNIQUE (device_id)
);
CREATE TABLE IF NOT EXISTS event (
id uuid NOT NULL CONSTRAINT event_pkey PRIMARY KEY,
created_time bigint NOT NULL,
body varchar(10000000),
entity_id uuid,
entity_type varchar(255),
event_type varchar(255),
event_uid varchar(255),
tenant_id uuid,
ts bigint NOT NULL,
CONSTRAINT event_unq_key UNIQUE (tenant_id, entity_type, entity_id, event_type, event_uid)
);
CREATE TABLE IF NOT EXISTS relation (
from_id uuid,
from_type varchar(255),
to_id uuid,
to_type varchar(255),
relation_type_group varchar(255),
relation_type varchar(255),
additional_info varchar,
CONSTRAINT relation_pkey PRIMARY KEY (from_id, from_type, relation_type_group, relation_type, to_id, to_type)
);
CREATE TABLE IF NOT EXISTS tb_user (
id uuid NOT NULL CONSTRAINT tb_user_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
authority varchar(255),
customer_id uuid,
email varchar(255) UNIQUE,
first_name varchar(255),
last_name varchar(255),
search_text varchar(255),
tenant_id uuid
);
CREATE TABLE IF NOT EXISTS tenant_profile (
id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
profile_data jsonb,
description varchar,
search_text varchar(255),
is_default boolean,
isolated_tb_core boolean,
isolated_tb_rule_engine boolean,
CONSTRAINT tenant_profile_name_unq_key UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS tenant (
id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
tenant_profile_id uuid NOT NULL,
address varchar,
address2 varchar,
city varchar(255),
country varchar(255),
email varchar(255),
phone varchar(255),
region varchar(255),
search_text varchar(255),
state varchar(255),
title varchar(255),
zip varchar(255),
CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id)
);
CREATE TABLE IF NOT EXISTS user_credentials (
id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY,
created_time bigint NOT NULL,
activate_token varchar(255) UNIQUE,
enabled boolean,
password varchar(255),
reset_token varchar(255) UNIQUE,
user_id uuid UNIQUE
);
CREATE TABLE IF NOT EXISTS widget_type (
id uuid NOT NULL CONSTRAINT widget_type_pkey PRIMARY KEY,
created_time bigint NOT NULL,
alias varchar(255),
bundle_alias varchar(255),
descriptor varchar(1000000),
name varchar(255),
tenant_id uuid,
image varchar(1000000),
description varchar(255)
);
CREATE TABLE IF NOT EXISTS widgets_bundle (
id uuid NOT NULL CONSTRAINT widgets_bundle_pkey PRIMARY KEY,
created_time bigint NOT NULL,
alias varchar(255),
search_text varchar(255),
tenant_id uuid,
title varchar(255),
image varchar(1000000),
description varchar(255)
);
CREATE TABLE IF NOT EXISTS entity_view (
id uuid NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY,
created_time bigint NOT NULL,
entity_id uuid,
entity_type varchar(255),
tenant_id uuid,
customer_id uuid,
type varchar(255),
name varchar(255),
keys varchar(10000000),
start_ts bigint,
end_ts bigint,
search_text varchar(255),
additional_info varchar
);
CREATE TABLE IF NOT EXISTS ts_kv_latest (
entity_id uuid NOT NULL,
key int NOT NULL,
ts bigint NOT NULL,
bool_v boolean,
str_v varchar(10000000),
long_v bigint,
dbl_v double precision,
json_v varchar(10000000),
CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key)
);
CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
key varchar(255) NOT NULL,
key_id int GENERATED BY DEFAULT AS IDENTITY(start with 0 increment by 1) UNIQUE,
CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
);
CREATE TABLE IF NOT EXISTS oauth2_params (
id uuid NOT NULL CONSTRAINT oauth2_params_pkey PRIMARY KEY,
enabled boolean,
tenant_id uuid,
created_time bigint NOT NULL
);
CREATE TABLE IF NOT EXISTS oauth2_registration (
id uuid NOT NULL CONSTRAINT oauth2_registration_pkey PRIMARY KEY,
oauth2_params_id uuid NOT NULL,
created_time bigint NOT NULL,
additional_info varchar,
client_id varchar(255),
client_secret varchar(2048),
authorization_uri varchar(255),
token_uri varchar(255),
scope varchar(255),
platforms varchar(255),
user_info_uri varchar(255),
user_name_attribute_name varchar(255),
jwk_set_uri varchar(255),
client_authentication_method varchar(255),
login_button_label varchar(255),
login_button_icon varchar(255),
allow_user_creation boolean,
activate_user boolean,
type varchar(31),
basic_email_attribute_key varchar(31),
basic_first_name_attribute_key varchar(31),
basic_last_name_attribute_key varchar(31),
basic_tenant_name_strategy varchar(31),
basic_tenant_name_pattern varchar(255),
basic_customer_name_pattern varchar(255),
basic_default_dashboard_name varchar(255),
basic_always_full_screen boolean,
custom_url varchar(255),
custom_username varchar(255),
custom_password varchar(255),
custom_send_token boolean,
CONSTRAINT fk_registration_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS oauth2_domain (
id uuid NOT NULL CONSTRAINT oauth2_domain_pkey PRIMARY KEY,
oauth2_params_id uuid NOT NULL,
created_time bigint NOT NULL,
domain_name varchar(255),
domain_scheme varchar(31),
CONSTRAINT fk_domain_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE,
CONSTRAINT oauth2_domain_unq_key UNIQUE (oauth2_params_id, domain_name, domain_scheme)
);
CREATE TABLE IF NOT EXISTS oauth2_mobile (
id uuid NOT NULL CONSTRAINT oauth2_mobile_pkey PRIMARY KEY,
oauth2_params_id uuid NOT NULL,
created_time bigint NOT NULL,
pkg_name varchar(255),
app_secret varchar(2048),
CONSTRAINT fk_mobile_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE,
CONSTRAINT oauth2_mobile_unq_key UNIQUE (oauth2_params_id, pkg_name)
);
CREATE TABLE IF NOT EXISTS oauth2_client_registration_template (
id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
provider_id varchar(255),
authorization_uri varchar(255),
token_uri varchar(255),
scope varchar(255),
user_info_uri varchar(255),
user_name_attribute_name varchar(255),
jwk_set_uri varchar(255),
client_authentication_method varchar(255),
type varchar(31),
basic_email_attribute_key varchar(31),
basic_first_name_attribute_key varchar(31),
basic_last_name_attribute_key varchar(31),
basic_tenant_name_strategy varchar(31),
basic_tenant_name_pattern varchar(255),
basic_customer_name_pattern varchar(255),
basic_default_dashboard_name varchar(255),
basic_always_full_screen boolean,
comment varchar,
login_button_icon varchar(255),
login_button_label varchar(255),
help_link varchar(255),
CONSTRAINT oauth2_template_provider_id_unq_key UNIQUE (provider_id)
);
-- Deprecated
CREATE TABLE IF NOT EXISTS oauth2_client_registration_info (
id uuid NOT NULL CONSTRAINT oauth2_client_registration_info_pkey PRIMARY KEY,
enabled boolean,
created_time bigint NOT NULL,
additional_info varchar,
client_id varchar(255),
client_secret varchar(255),
authorization_uri varchar(255),
token_uri varchar(255),
scope varchar(255),
user_info_uri varchar(255),
user_name_attribute_name varchar(255),
jwk_set_uri varchar(255),
client_authentication_method varchar(255),
login_button_label varchar(255),
login_button_icon varchar(255),
allow_user_creation boolean,
activate_user boolean,
type varchar(31),
basic_email_attribute_key varchar(31),
basic_first_name_attribute_key varchar(31),
basic_last_name_attribute_key varchar(31),
basic_tenant_name_strategy varchar(31),
basic_tenant_name_pattern varchar(255),
basic_customer_name_pattern varchar(255),
basic_default_dashboard_name varchar(255),
basic_always_full_screen boolean,
custom_url varchar(255),
custom_username varchar(255),
custom_password varchar(255),
custom_send_token boolean
);
-- Deprecated
CREATE TABLE IF NOT EXISTS oauth2_client_registration (
id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY,
created_time bigint NOT NULL,
domain_name varchar(255),
domain_scheme varchar(31),
client_registration_info_id uuid
);
CREATE TABLE IF NOT EXISTS api_usage_state (
id uuid NOT NULL CONSTRAINT usage_record_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid,
entity_type varchar(32),
entity_id uuid,
transport varchar(32),
db_storage varchar(32),
re_exec varchar(32),
js_exec varchar(32),
email_exec varchar(32),
sms_exec varchar(32),
alarm_exec varchar(32),
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
);
CREATE TABLE IF NOT EXISTS resource (
id uuid NOT NULL CONSTRAINT resource_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
title varchar(255) NOT NULL,
resource_type varchar(32) NOT NULL,
resource_key varchar(255) NOT NULL,
search_text varchar(255),
file_name varchar(255) NOT NULL,
data varchar,
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key)
);
CREATE TABLE IF NOT EXISTS edge (
id uuid NOT NULL CONSTRAINT edge_pkey PRIMARY KEY,
created_time bigint NOT NULL,
additional_info varchar,
customer_id uuid,
root_rule_chain_id uuid,
type varchar(255),
name varchar(255),
label varchar(255),
routing_key varchar(255),
secret varchar(255),
edge_license_key varchar(30),
cloud_endpoint varchar(255),
search_text varchar(255),
tenant_id uuid,
CONSTRAINT edge_name_unq_key UNIQUE (tenant_id, name),
CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key)
);
CREATE TABLE IF NOT EXISTS edge_event (
id uuid NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY,
created_time bigint NOT NULL,
edge_id uuid,
edge_event_type varchar(255),
edge_event_uid varchar(255),
entity_id uuid,
edge_event_action varchar(255),
body varchar(10000000),
tenant_id uuid,
ts bigint NOT NULL
);
CREATE TABLE IF NOT EXISTS rpc (
id uuid NOT NULL CONSTRAINT rpc_pkey PRIMARY KEY,
created_time bigint NOT NULL,
tenant_id uuid NOT NULL,
device_id uuid NOT NULL,
expiration_time bigint NOT NULL,
request varchar(10000000) NOT NULL,
response varchar(10000000),
additional_info varchar(10000000),
status varchar(255) NOT NULL
);

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

@ -55,7 +55,9 @@ CREATE TABLE IF NOT EXISTS alarm (
tenant_id uuid, tenant_id uuid,
customer_id uuid, customer_id uuid,
propagate_relation_types varchar, propagate_relation_types varchar,
type varchar(255) type varchar(255),
propagate_to_owner boolean,
propagate_to_tenant boolean
); );
CREATE TABLE IF NOT EXISTS entity_alarm ( CREATE TABLE IF NOT EXISTS entity_alarm (

41
dao/src/main/resources/sql/schema-ts-hsql.sql

@ -1,41 +0,0 @@
--
-- 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.
--
SET DATABASE SQL SYNTAX PGS TRUE;
SET DATABASE TRANSACTION CONTROL MVCC;
CREATE TABLE IF NOT EXISTS ts_kv (
entity_id uuid NOT NULL,
key int NOT NULL,
ts bigint NOT NULL,
bool_v boolean,
str_v varchar(10000000),
long_v bigint,
dbl_v double precision,
json_v varchar(10000000),
CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts)
);
CREATE TABLE IF NOT EXISTS ts_kv_dictionary (
key varchar(255) NOT NULL,
key_id int GENERATED BY DEFAULT AS IDENTITY(start with 0 increment by 1) UNIQUE,
CONSTRAINT ts_key_id_pkey PRIMARY KEY (key)
);
CREATE FUNCTION to_uuid(IN entity_id varchar)
RETURNS UUID
RETURN UUID(substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) ||
'-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12));

20
dao/src/main/resources/sql/schema-types-hsql.sql

@ -1,20 +0,0 @@
--
-- 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.
--
DROP TYPE json IF EXISTS;
CREATE TYPE json AS varchar;
DROP TYPE jsonb IF EXISTS;
CREATE TYPE jsonb AS other;

78
dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java

@ -264,10 +264,10 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
PageData<AlarmData> tenantAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Arrays.asList(tenantDevice.getId(), customerDevice.getId())); PageData<AlarmData> tenantAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Arrays.asList(tenantDevice.getId(), customerDevice.getId()));
Assert.assertEquals(2, tenantAlarms.getData().size()); Assert.assertEquals(2, tenantAlarms.getData().size());
PageData<AlarmData> customerAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, customer.getId(), toQuery(pageLink), Collections.singletonList(customerDevice.getId())); PageData<AlarmData> customerAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(customerDevice.getId()));
Assert.assertEquals(1, customerAlarms.getData().size()); Assert.assertEquals(1, customerAlarms.getData().size());
Assert.assertEquals(deviceAlarm, customerAlarms.getData().get(0)); Assert.assertEquals(deviceAlarm, customerAlarms.getData().get(0));
@ -283,7 +283,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
} }
@Test @Test
public void testFindPopagatedCustomerAlarm() throws ExecutionException, InterruptedException { public void testFindPropagatedCustomerAssetAlarm() throws ExecutionException, InterruptedException {
Customer customer = new Customer(); Customer customer = new Customer();
customer.setTitle("TestCustomer"); customer.setTitle("TestCustomer");
customer.setTenantId(tenantId); customer.setTenantId(tenantId);
@ -341,7 +341,63 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
//TEST that propagated alarms are visible on the asset level. //TEST that propagated alarms are visible on the asset level.
PageData<AlarmData> customerAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, customer.getId(), toQuery(pageLink), Collections.singletonList(customerAsset.getId())); PageData<AlarmData> customerAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(customerAsset.getId()));
Assert.assertEquals(1, customerAlarms.getData().size());
Assert.assertEquals(customerAlarm, customerAlarms.getData().get(0));
}
@Test
public void testFindPropagatedToOwnerAndTenantAlarm() {
Customer customer = new Customer();
customer.setTitle("TestCustomer");
customer.setTenantId(tenantId);
customer = customerService.saveCustomer(customer);
Device device = new Device();
device.setName("TestTenantDevice");
device.setType("default");
device.setTenantId(tenantId);
device.setCustomerId(customer.getId());
device = deviceService.saveDevice(device);
long ts = System.currentTimeMillis();
Alarm tenantAlarm = Alarm.builder().tenantId(tenantId)
.originator(device.getId())
.type("Propagated To Tenant")
.propagateToTenant(true)
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm();
Alarm customerAlarm = Alarm.builder().tenantId(tenantId)
.originator(device.getId())
.type("Propagated to Customer")
.propagate(false)
.propagateToOwner(true)
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
result = alarmService.createOrUpdateAlarm(customerAlarm);
customerAlarm = result.getAlarm();
AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0);
pageLink.setPageSize(10);
pageLink.setSortOrder(new EntityDataSortOrder(new EntityKey(EntityKeyType.ALARM_FIELD, "createdTime")));
pageLink.setStartTs(0L);
pageLink.setEndTs(System.currentTimeMillis());
pageLink.setSearchPropagatedAlarms(true);
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
//TEST that propagated alarms are visible on the asset level.
PageData<AlarmData> tenantAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(tenantId));
Assert.assertEquals(1, tenantAlarms.getData().size());
Assert.assertEquals(tenantAlarm, tenantAlarms.getData().get(0));
//TEST that propagated alarms are visible on the asset level.
PageData<AlarmData> customerAlarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(customer.getId()));
Assert.assertEquals(1, customerAlarms.getData().size()); Assert.assertEquals(1, customerAlarms.getData().size());
Assert.assertEquals(customerAlarm, customerAlarms.getData().get(0)); Assert.assertEquals(customerAlarm, customerAlarms.getData().get(0));
} }
@ -444,7 +500,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(childId)); PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(childId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size()); Assert.assertEquals(1, alarms.getData().size());
@ -460,13 +516,13 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(childId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(childId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size()); Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new Alarm(alarms.getData().get(0))); Assert.assertEquals(created, new Alarm(alarms.getData().get(0)));
pageLink.setSearchPropagatedAlarms(true); pageLink.setSearchPropagatedAlarms(true);
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(childId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(childId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size()); Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, new Alarm(alarms.getData().get(0))); Assert.assertEquals(created, new Alarm(alarms.getData().get(0)));
@ -487,7 +543,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(childId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(childId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
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));
@ -503,7 +559,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(parentId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(parentId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
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));
@ -548,7 +604,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(parentId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(parentId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
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));
@ -566,7 +622,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING)); pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE)); pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, new CustomerId(CustomerId.NULL_UUID), toQuery(pageLink), Collections.singletonList(childId)); alarms = alarmService.findAlarmDataByQueryForEntities(tenantId, toQuery(pageLink), Collections.singletonList(childId));
Assert.assertNotNull(alarms.getData()); Assert.assertNotNull(alarms.getData());
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));

2
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java

@ -61,5 +61,5 @@ public interface RuleEngineAlarmService {
AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, AlarmStatus alarmStatus); AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus, AlarmStatus alarmStatus);
PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds); PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
} }

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java

@ -145,10 +145,14 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
if (msgAlarm != null) { if (msgAlarm != null) {
existingAlarm.setSeverity(msgAlarm.getSeverity()); existingAlarm.setSeverity(msgAlarm.getSeverity());
existingAlarm.setPropagate(msgAlarm.isPropagate()); existingAlarm.setPropagate(msgAlarm.isPropagate());
existingAlarm.setPropagateToOwner(msgAlarm.isPropagateToOwner());
existingAlarm.setPropagateToTenant(msgAlarm.isPropagateToTenant());
existingAlarm.setPropagateRelationTypes(msgAlarm.getPropagateRelationTypes()); existingAlarm.setPropagateRelationTypes(msgAlarm.getPropagateRelationTypes());
} else { } else {
existingAlarm.setSeverity(processAlarmSeverity(msg)); existingAlarm.setSeverity(processAlarmSeverity(msg));
existingAlarm.setPropagate(config.isPropagate()); existingAlarm.setPropagate(config.isPropagate());
existingAlarm.setPropagateToOwner(config.isPropagateToOwner());
existingAlarm.setPropagateToTenant(config.isPropagateToTenant());
existingAlarm.setPropagateRelationTypes(relationTypes); existingAlarm.setPropagateRelationTypes(relationTypes);
} }
existingAlarm.setDetails(details); existingAlarm.setDetails(details);

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java

@ -27,6 +27,8 @@ public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigura
private String severity; private String severity;
private boolean propagate; private boolean propagate;
private boolean propagateToOwner;
private boolean propagateToTenant;
private boolean useMessageAlarmData; private boolean useMessageAlarmData;
private boolean dynamicSeverity; private boolean dynamicSeverity;
@ -39,6 +41,8 @@ public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigura
configuration.setAlarmType("General Alarm"); configuration.setAlarmType("General Alarm");
configuration.setSeverity(AlarmSeverity.CRITICAL.name()); configuration.setSeverity(AlarmSeverity.CRITICAL.name());
configuration.setPropagate(false); configuration.setPropagate(false);
configuration.setPropagateToOwner(false);
configuration.setPropagateToTenant(false);
configuration.setUseMessageAlarmData(false); configuration.setUseMessageAlarmData(false);
configuration.setRelationTypes(Collections.emptyList()); configuration.setRelationTypes(Collections.emptyList());
configuration.setDynamicSeverity(false); configuration.setDynamicSeverity(false);

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java

@ -258,6 +258,8 @@ class AlarmState {
currentAlarm.setOriginator(originator); currentAlarm.setOriginator(originator);
currentAlarm.setTenantId(ctx.getTenantId()); currentAlarm.setTenantId(ctx.getTenantId());
currentAlarm.setPropagate(alarmDefinition.isPropagate()); currentAlarm.setPropagate(alarmDefinition.isPropagate());
currentAlarm.setPropagateToOwner(alarmDefinition.isPropagateToOwner());
currentAlarm.setPropagateToTenant(alarmDefinition.isPropagateToTenant());
if (alarmDefinition.getPropagateRelationTypes() != null) { if (alarmDefinition.getPropagateRelationTypes() != null) {
currentAlarm.setPropagateRelationTypes(alarmDefinition.getPropagateRelationTypes()); currentAlarm.setPropagateRelationTypes(alarmDefinition.getPropagateRelationTypes());
} }

Loading…
Cancel
Save