Propagate alarms to Customer or Tenant without relations
This commit is contained in:
		
							parent
							
								
									ce085ea9a0
								
							
						
					
					
						commit
						66b58549c5
					
				@ -71,7 +71,9 @@ public class AlarmMsgConstructor {
 | 
			
		||||
                .setAckTs(alarm.getAckTs())
 | 
			
		||||
                .setClearTs(alarm.getClearTs())
 | 
			
		||||
                .setDetails(JacksonUtil.toString(alarm.getDetails()))
 | 
			
		||||
                .setPropagate(alarm.isPropagate());
 | 
			
		||||
                .setPropagate(alarm.isPropagate())
 | 
			
		||||
                .setPropagateToOwner(alarm.isPropagateToOwner())
 | 
			
		||||
                .setPropagateToTenant(alarm.isPropagateToTenant());
 | 
			
		||||
        return builder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -475,6 +475,12 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
 | 
			
		||||
                    log.info("Updating schema ...");
 | 
			
		||||
                    schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.2", SCHEMA_UPDATE_SQL);
 | 
			
		||||
                    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 {
 | 
			
		||||
                        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;");
 | 
			
		||||
 | 
			
		||||
@ -106,8 +106,7 @@ public class DefaultEntityQueryService implements EntityQueryService {
 | 
			
		||||
            for (EntityData entityData : entities.getData()) {
 | 
			
		||||
                entitiesMap.put(entityData.getEntityId(), entityData);
 | 
			
		||||
            }
 | 
			
		||||
            PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(securityUser.getTenantId(),
 | 
			
		||||
                    securityUser.getCustomerId(), query, entitiesMap.keySet());
 | 
			
		||||
            PageData<AlarmData> alarms = alarmService.findAlarmDataByQueryForEntities(securityUser.getTenantId(), query, entitiesMap.keySet());
 | 
			
		||||
            for (AlarmData alarmData : alarms.getData()) {
 | 
			
		||||
                EntityId entityId = alarmData.getEntityId();
 | 
			
		||||
                if (entityId != null) {
 | 
			
		||||
 | 
			
		||||
@ -106,7 +106,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
 | 
			
		||||
        AlarmDataUpdate update;
 | 
			
		||||
        if (!entitiesMap.isEmpty()) {
 | 
			
		||||
            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();
 | 
			
		||||
            stats.getAlarmQueryInvocationCnt().incrementAndGet();
 | 
			
		||||
            stats.getAlarmQueryTimeSpent().addAndGet(end - start);
 | 
			
		||||
 | 
			
		||||
@ -150,8 +150,8 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
 | 
			
		||||
        return alarmService.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
 | 
			
		||||
        return alarmService.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,7 @@ public interface AlarmService {
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId);
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,11 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha
 | 
			
		||||
    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")
 | 
			
		||||
    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. " +
 | 
			
		||||
            "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;
 | 
			
		||||
@ -98,6 +102,8 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha
 | 
			
		||||
        this.clearTs = alarm.getClearTs();
 | 
			
		||||
        this.details = alarm.getDetails();
 | 
			
		||||
        this.propagate = alarm.isPropagate();
 | 
			
		||||
        this.propagateToOwner = alarm.isPropagateToOwner();
 | 
			
		||||
        this.propagateToTenant = alarm.isPropagateToTenant();
 | 
			
		||||
        this.propagateRelationTypes = alarm.getPropagateRelationTypes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ public class AlarmInfo extends Alarm {
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    public AlarmInfo() {
 | 
			
		||||
 | 
			
		||||
@ -49,8 +49,14 @@ public class DeviceProfileAlarm implements Serializable {
 | 
			
		||||
    // 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")
 | 
			
		||||
    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. " +
 | 
			
		||||
            "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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -269,6 +269,8 @@ message AlarmUpdateMsg {
 | 
			
		||||
  int64 clearTs = 13;
 | 
			
		||||
  string details = 14;
 | 
			
		||||
  bool propagate = 15;
 | 
			
		||||
  bool propagateToOwner = 16;
 | 
			
		||||
  bool propagateToTenant = 17;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message CustomerUpdateMsg {
 | 
			
		||||
 | 
			
		||||
@ -54,8 +54,7 @@ public interface AlarmDao extends Dao<Alarm> {
 | 
			
		||||
 | 
			
		||||
    PageData<AlarmInfo> findCustomerAlarms(TenantId tenantId, CustomerId customerId, AlarmQuery query);
 | 
			
		||||
 | 
			
		||||
    PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId,
 | 
			
		||||
                                                        AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
 | 
			
		||||
    PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
 | 
			
		||||
 | 
			
		||||
    Set<AlarmSeverity> findAlarmSeverities(TenantId tenantId, EntityId entityId, Set<AlarmStatus> status);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,7 @@ import javax.annotation.PreDestroy;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
@ -139,11 +140,10 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId,
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
 | 
			
		||||
                                                               AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
 | 
			
		||||
        validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
 | 
			
		||||
        validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
 | 
			
		||||
        return alarmDao.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
 | 
			
		||||
        return alarmDao.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -171,25 +171,25 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
 | 
			
		||||
        List<EntityId> propagatedEntitiesList;
 | 
			
		||||
        Set<EntityId> propagatedEntitiesSet = new LinkedHashSet<>();
 | 
			
		||||
        propagatedEntitiesSet.add(alarm.getOriginator());
 | 
			
		||||
        if (alarm.isPropagate()) {
 | 
			
		||||
            Set<EntityId> parentEntities = getParentEntities(alarm);
 | 
			
		||||
            propagatedEntitiesList = new ArrayList<>(parentEntities.size() + 1);
 | 
			
		||||
            for (EntityId parentId : parentEntities) {
 | 
			
		||||
                propagatedEntitiesList.add(parentId);
 | 
			
		||||
                createEntityAlarmRecord(alarm.getTenantId(), parentId, alarm);
 | 
			
		||||
            }
 | 
			
		||||
            propagatedEntitiesList.add(alarm.getOriginator());
 | 
			
		||||
        } else {
 | 
			
		||||
            propagatedEntitiesList = Collections.singletonList(alarm.getOriginator());
 | 
			
		||||
            propagatedEntitiesSet.addAll(getRelatedEntities(alarm));
 | 
			
		||||
        }
 | 
			
		||||
        createEntityAlarmRecord(alarm.getTenantId(), alarm.getOriginator(), alarm);
 | 
			
		||||
        return propagatedEntitiesList;
 | 
			
		||||
        if (alarm.isPropagateToOwner()) {
 | 
			
		||||
            propagatedEntitiesSet.add(alarm.getCustomerId() != null ? alarm.getCustomerId() : alarm.getTenantId());
 | 
			
		||||
        }
 | 
			
		||||
        if (alarm.isPropagateToTenant()) {
 | 
			
		||||
            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();
 | 
			
		||||
        //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);
 | 
			
		||||
        query.setParameters(parameters);
 | 
			
		||||
        List<String> propagateRelationTypes = alarm.getPropagateRelationTypes();
 | 
			
		||||
@ -216,11 +216,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private AlarmOperationResult updateAlarm(Alarm oldAlarm, Alarm newAlarm) {
 | 
			
		||||
        boolean oldPropagate = oldAlarm.isPropagate();
 | 
			
		||||
        boolean newPropagate = newAlarm.isPropagate();
 | 
			
		||||
        boolean propagationEnabled = !oldAlarm.isPropagate() && newAlarm.isPropagate();
 | 
			
		||||
        boolean propagationToOwnerEnabled = !oldAlarm.isPropagateToOwner() && newAlarm.isPropagateToOwner();
 | 
			
		||||
        boolean propagationToTenantEnabled = !oldAlarm.isPropagateToTenant() && newAlarm.isPropagateToTenant();
 | 
			
		||||
        Alarm result = alarmDao.save(newAlarm.getTenantId(), merge(oldAlarm, newAlarm));
 | 
			
		||||
        List<EntityId> propagatedEntitiesList;
 | 
			
		||||
        if (!oldPropagate && newPropagate) {
 | 
			
		||||
        if (propagationEnabled || propagationToOwnerEnabled || propagationToTenantEnabled) {
 | 
			
		||||
            try {
 | 
			
		||||
                propagatedEntitiesList = createEntityAlarmRecords(result);
 | 
			
		||||
            } catch (InterruptedException | ExecutionException e) {
 | 
			
		||||
@ -372,6 +373,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
        existing.setDetails(alarm.getDetails());
 | 
			
		||||
        existing.setCustomerId(alarm.getCustomerId());
 | 
			
		||||
        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> newRelationTypes = alarm.getPropagateRelationTypes();
 | 
			
		||||
        if (!CollectionUtils.isEmpty(newRelationTypes)) {
 | 
			
		||||
@ -387,7 +390,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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());
 | 
			
		||||
            return entityAlarms.stream().map(EntityAlarm::getEntityId).collect(Collectors.toSet());
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
@ -273,6 +273,8 @@ public class ModelConstants {
 | 
			
		||||
    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_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_BY_ID_VIEW_NAME = "alarm_by_id";
 | 
			
		||||
 | 
			
		||||
@ -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_PROPAGATE_PROPERTY;
 | 
			
		||||
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_START_TS_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)
 | 
			
		||||
    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)
 | 
			
		||||
    private String propagateRelationTypes;
 | 
			
		||||
 | 
			
		||||
@ -130,6 +138,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
 | 
			
		||||
        this.severity = alarm.getSeverity();
 | 
			
		||||
        this.status = alarm.getStatus();
 | 
			
		||||
        this.propagate = alarm.isPropagate();
 | 
			
		||||
        this.propagateToOwner = alarm.isPropagateToOwner();
 | 
			
		||||
        this.propagateToTenant = alarm.isPropagateToTenant();
 | 
			
		||||
        this.startTs = alarm.getStartTs();
 | 
			
		||||
        this.endTs = alarm.getEndTs();
 | 
			
		||||
        this.ackTs = alarm.getAckTs();
 | 
			
		||||
@ -154,6 +164,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
 | 
			
		||||
        this.severity = alarmEntity.getSeverity();
 | 
			
		||||
        this.status = alarmEntity.getStatus();
 | 
			
		||||
        this.propagate = alarmEntity.getPropagate();
 | 
			
		||||
        this.propagateToOwner = alarmEntity.getPropagateToOwner();
 | 
			
		||||
        this.propagateToTenant = alarmEntity.getPropagateToTenant();
 | 
			
		||||
        this.startTs = alarmEntity.getStartTs();
 | 
			
		||||
        this.endTs = alarmEntity.getEndTs();
 | 
			
		||||
        this.ackTs = alarmEntity.getAckTs();
 | 
			
		||||
@ -176,6 +188,8 @@ public abstract class AbstractAlarmEntity<T extends Alarm> extends BaseSqlEntity
 | 
			
		||||
        alarm.setSeverity(severity);
 | 
			
		||||
        alarm.setStatus(status);
 | 
			
		||||
        alarm.setPropagate(propagate);
 | 
			
		||||
        alarm.setPropagateToOwner(propagateToOwner);
 | 
			
		||||
        alarm.setPropagateToTenant(propagateToTenant);
 | 
			
		||||
        alarm.setStartTs(startTs);
 | 
			
		||||
        alarm.setEndTs(endTs);
 | 
			
		||||
        alarm.setAckTs(ackTs);
 | 
			
		||||
 | 
			
		||||
@ -157,8 +157,8 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
 | 
			
		||||
        return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, customerId, query, orderedEntityIds);
 | 
			
		||||
    public PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, AlarmDataQuery query, Collection<EntityId> orderedEntityIds) {
 | 
			
		||||
        return alarmQueryRepository.findAlarmDataByQueryForEntities(tenantId, query, orderedEntityIds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,8 @@ public class AlarmDataAdapter {
 | 
			
		||||
        UUID originatorId = (UUID) row.get(ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY);
 | 
			
		||||
        alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId));
 | 
			
		||||
        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.setSeverity(AlarmSeverity.valueOf(row.get(ModelConstants.ALARM_SEVERITY_PROPERTY).toString()));
 | 
			
		||||
        alarm.setStatus(AlarmStatus.valueOf(row.get(ModelConstants.ALARM_STATUS_PROPERTY).toString()));
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
public interface AlarmQueryRepository {
 | 
			
		||||
 | 
			
		||||
    PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId, CustomerId customerId,
 | 
			
		||||
    PageData<AlarmData> findAlarmDataByQueryForEntities(TenantId tenantId,
 | 
			
		||||
                                                        AlarmDataQuery query, Collection<EntityId> orderedEntityIds);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -97,6 +97,8 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
 | 
			
		||||
            " a.originator_id as originator_id," +
 | 
			
		||||
            " a.originator_type as originator_type," +
 | 
			
		||||
            " 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.start_ts as start_ts," +
 | 
			
		||||
            " a.status as status, " +
 | 
			
		||||
@ -119,11 +121,10 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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 transactionTemplate.execute(status -> {
 | 
			
		||||
            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()));
 | 
			
		||||
            StringBuilder selectPart = new StringBuilder(FIELDS_SELECTION);
 | 
			
		||||
            StringBuilder fromPart = new StringBuilder(" from alarm a ");
 | 
			
		||||
@ -134,7 +135,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
 | 
			
		||||
            if (pageLink.isSearchPropagatedAlarms()) {
 | 
			
		||||
                selectPart.append(" ea.entity_id as entity_id ");
 | 
			
		||||
                fromPart.append(JOIN_ENTITY_ALARMS);
 | 
			
		||||
                wherePart.append(buildPermissionsQuery(tenantId, customerId, ctx));
 | 
			
		||||
                wherePart.append(buildPermissionsQuery(tenantId, ctx));
 | 
			
		||||
                addAnd = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                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();
 | 
			
		||||
        ctx.addUuidParameter("permissions_tenant_id", tenantId.getId());
 | 
			
		||||
        permissionsQuery.append(" a.tenant_id = :permissions_tenant_id and ea.tenant_id = :permissions_tenant_id ");
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
);
 | 
			
		||||
@ -55,7 +55,9 @@ CREATE TABLE IF NOT EXISTS alarm (
 | 
			
		||||
    tenant_id uuid,
 | 
			
		||||
    customer_id uuid,
 | 
			
		||||
    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 (
 | 
			
		||||
 | 
			
		||||
@ -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));
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -264,10 +264,10 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
 | 
			
		||||
        pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
 | 
			
		||||
        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());
 | 
			
		||||
 | 
			
		||||
        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(deviceAlarm, customerAlarms.getData().get(0));
 | 
			
		||||
 | 
			
		||||
@ -283,7 +283,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testFindPopagatedCustomerAlarm() throws ExecutionException, InterruptedException {
 | 
			
		||||
    public void testFindPropagatedCustomerAssetAlarm() throws ExecutionException, InterruptedException {
 | 
			
		||||
        Customer customer = new Customer();
 | 
			
		||||
        customer.setTitle("TestCustomer");
 | 
			
		||||
        customer.setTenantId(tenantId);
 | 
			
		||||
@ -341,7 +341,63 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
 | 
			
		||||
        pageLink.setStatusList(Arrays.asList(AlarmSearchStatus.ACTIVE));
 | 
			
		||||
 | 
			
		||||
        //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(customerAlarm, customerAlarms.getData().get(0));
 | 
			
		||||
    }
 | 
			
		||||
@ -444,7 +500,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
 | 
			
		||||
        pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
 | 
			
		||||
        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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
@ -460,13 +516,13 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
 | 
			
		||||
        pageLink.setSeverityList(Arrays.asList(AlarmSeverity.CRITICAL, AlarmSeverity.WARNING));
 | 
			
		||||
        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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        Assert.assertEquals(created, new Alarm(alarms.getData().get(0)));
 | 
			
		||||
 | 
			
		||||
        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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        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.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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        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.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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        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.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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        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.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.assertEquals(1, alarms.getData().size());
 | 
			
		||||
        Assert.assertEquals(created, alarms.getData().get(0));
 | 
			
		||||
 | 
			
		||||
@ -61,5 +61,5 @@ public interface RuleEngineAlarmService {
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -145,10 +145,14 @@ public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConf
 | 
			
		||||
            if (msgAlarm != null) {
 | 
			
		||||
                existingAlarm.setSeverity(msgAlarm.getSeverity());
 | 
			
		||||
                existingAlarm.setPropagate(msgAlarm.isPropagate());
 | 
			
		||||
                existingAlarm.setPropagateToOwner(msgAlarm.isPropagateToOwner());
 | 
			
		||||
                existingAlarm.setPropagateToTenant(msgAlarm.isPropagateToTenant());
 | 
			
		||||
                existingAlarm.setPropagateRelationTypes(msgAlarm.getPropagateRelationTypes());
 | 
			
		||||
            } else {
 | 
			
		||||
                existingAlarm.setSeverity(processAlarmSeverity(msg));
 | 
			
		||||
                existingAlarm.setPropagate(config.isPropagate());
 | 
			
		||||
                existingAlarm.setPropagateToOwner(config.isPropagateToOwner());
 | 
			
		||||
                existingAlarm.setPropagateToTenant(config.isPropagateToTenant());
 | 
			
		||||
                existingAlarm.setPropagateRelationTypes(relationTypes);
 | 
			
		||||
            }
 | 
			
		||||
            existingAlarm.setDetails(details);
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,8 @@ public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigura
 | 
			
		||||
 | 
			
		||||
    private String severity;
 | 
			
		||||
    private boolean propagate;
 | 
			
		||||
    private boolean propagateToOwner;
 | 
			
		||||
    private boolean propagateToTenant;
 | 
			
		||||
    private boolean useMessageAlarmData;
 | 
			
		||||
    private boolean dynamicSeverity;
 | 
			
		||||
 | 
			
		||||
@ -39,6 +41,8 @@ public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigura
 | 
			
		||||
        configuration.setAlarmType("General Alarm");
 | 
			
		||||
        configuration.setSeverity(AlarmSeverity.CRITICAL.name());
 | 
			
		||||
        configuration.setPropagate(false);
 | 
			
		||||
        configuration.setPropagateToOwner(false);
 | 
			
		||||
        configuration.setPropagateToTenant(false);
 | 
			
		||||
        configuration.setUseMessageAlarmData(false);
 | 
			
		||||
        configuration.setRelationTypes(Collections.emptyList());
 | 
			
		||||
        configuration.setDynamicSeverity(false);
 | 
			
		||||
 | 
			
		||||
@ -258,6 +258,8 @@ class AlarmState {
 | 
			
		||||
            currentAlarm.setOriginator(originator);
 | 
			
		||||
            currentAlarm.setTenantId(ctx.getTenantId());
 | 
			
		||||
            currentAlarm.setPropagate(alarmDefinition.isPropagate());
 | 
			
		||||
            currentAlarm.setPropagateToOwner(alarmDefinition.isPropagateToOwner());
 | 
			
		||||
            currentAlarm.setPropagateToTenant(alarmDefinition.isPropagateToTenant());
 | 
			
		||||
            if (alarmDefinition.getPropagateRelationTypes() != null) {
 | 
			
		||||
                currentAlarm.setPropagateRelationTypes(alarmDefinition.getPropagateRelationTypes());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user