Browse Source

CF: make type+name unique instead of just name

pull/14193/head
VIacheslavKlimov 10 months ago
parent
commit
89753ed8ea
  1. 7
      application/src/main/data/upgrade/basic/schema_update.sql
  2. 2
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java
  3. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/cf/BaseCalculatedFieldProcessor.java
  4. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/cf/CalculatedFieldService.java
  5. 11
      dao/src/main/java/org/thingsboard/server/dao/cf/BaseCalculatedFieldService.java
  6. 2
      dao/src/main/java/org/thingsboard/server/dao/cf/CalculatedFieldDao.java
  7. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/cf/CalculatedFieldRepository.java
  8. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/cf/JpaCalculatedFieldDao.java
  9. 2
      dao/src/main/resources/sql/schema-entities.sql
  10. 2
      dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java

7
application/src/main/data/upgrade/basic/schema_update.sql

@ -46,3 +46,10 @@ WHERE NOT (
);
-- UPDATE TENANT PROFILE CONFIGURATION END
-- CALCULATED FIELD UNIQUE CONSTRAINT UPDATE START
ALTER TABLE calculated_field DROP CONSTRAINT IF EXISTS calculated_field_unq_key;
ALTER TABLE calculated_field ADD CONSTRAINT calculated_field_unq_key UNIQUE (entity_id, type, name);
-- CALCULATED FIELD UNIQUE CONSTRAINT UPDATE END

2
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java

@ -189,6 +189,8 @@ public class AlarmCalculatedFieldState extends BaseCalculatedFieldState {
@Override
public ListenableFuture<CalculatedFieldResult> performCalculation(Map<String, ArgumentEntry> updatedArgs, CalculatedFieldCtx ctx) {
initCurrentAlarm(ctx);
// FIXME: don't create alarm if attrs were deleted, or config is updated
// TODO: what if expression is changed? do we reevaluate? or only on new events?
TbAlarmResult result = createOrClearAlarms(state -> {
if (updatedArgs != null) {
boolean newEvent = !updatedArgs.isEmpty();

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/cf/BaseCalculatedFieldProcessor.java

@ -53,7 +53,7 @@ public abstract class BaseCalculatedFieldProcessor extends BaseEdgeProcessor {
}
String calculatedFieldName = calculatedField.getName();
CalculatedField calculatedFieldByName = edgeCtx.getCalculatedFieldService().findByEntityIdAndName(calculatedField.getEntityId(), calculatedFieldName);
CalculatedField calculatedFieldByName = edgeCtx.getCalculatedFieldService().findByEntityIdAndTypeAndName(calculatedField.getEntityId(), calculatedField.getType(), calculatedFieldName);
if (calculatedFieldByName != null && !calculatedFieldByName.getId().equals(calculatedFieldId)) {
calculatedFieldName = calculatedFieldName + "_" + StringUtils.randomAlphabetic(15);
log.warn("[{}] calculatedField with name {} already exists. Renaming calculatedField name to {}",

2
common/dao-api/src/main/java/org/thingsboard/server/dao/cf/CalculatedFieldService.java

@ -36,7 +36,7 @@ public interface CalculatedFieldService extends EntityDaoService {
CalculatedField findById(TenantId tenantId, CalculatedFieldId calculatedFieldId);
CalculatedField findByEntityIdAndName(EntityId entityId, String name);
CalculatedField findByEntityIdAndTypeAndName(EntityId entityId, CalculatedFieldType type, String name);
List<CalculatedFieldId> findCalculatedFieldIdsByEntityId(TenantId tenantId, EntityId entityId);

11
dao/src/main/java/org/thingsboard/server/dao/cf/BaseCalculatedFieldService.java

@ -89,8 +89,9 @@ public class BaseCalculatedFieldService extends AbstractEntityService implements
return savedCalculatedField;
} catch (Exception e) {
checkConstraintViolation(e,
"calculated_field_unq_key", "Calculated Field with such name is already in exists!",
"calculated_field_external_id_unq_key", "Calculated Field with such external id already exists!");
"calculated_field_unq_key", calculatedField.getType() == CalculatedFieldType.ALARM ?
"Alarm rule with such type already exists" : "Calculated field with such name and type already exists",
"calculated_field_external_id_unq_key", "Calculated field with such external id already exists");
throw e;
}
}
@ -104,10 +105,10 @@ public class BaseCalculatedFieldService extends AbstractEntityService implements
}
@Override
public CalculatedField findByEntityIdAndName(EntityId entityId, String name) {
log.trace("Executing findByEntityIdAndName [{}], calculatedFieldName[{}]", entityId, name);
public CalculatedField findByEntityIdAndTypeAndName(EntityId entityId, CalculatedFieldType type, String name) {
log.trace("Executing findByEntityIdAndTypeAndName entityId [{}], type [{}], name [{}]", entityId, type, name);
validateId(entityId.getId(), id -> INCORRECT_ENTITY_ID + id);
return calculatedFieldDao.findByEntityIdAndName(entityId, name);
return calculatedFieldDao.findByEntityIdAndTypeAndName(entityId, type, name);
}
@Override

2
dao/src/main/java/org/thingsboard/server/dao/cf/CalculatedFieldDao.java

@ -37,7 +37,7 @@ public interface CalculatedFieldDao extends Dao<CalculatedField> {
List<CalculatedField> findAll();
CalculatedField findByEntityIdAndName(EntityId entityId, String name);
CalculatedField findByEntityIdAndTypeAndName(EntityId entityId, CalculatedFieldType type, String name);
PageData<CalculatedField> findAll(PageLink pageLink);

3
dao/src/main/java/org/thingsboard/server/dao/sql/cf/CalculatedFieldRepository.java

@ -19,6 +19,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.thingsboard.server.common.data.cf.CalculatedFieldType;
import org.thingsboard.server.common.data.id.CalculatedFieldId;
import org.thingsboard.server.dao.model.sql.CalculatedFieldEntity;
@ -29,7 +30,7 @@ public interface CalculatedFieldRepository extends JpaRepository<CalculatedField
boolean existsByTenantIdAndEntityId(UUID tenantId, UUID entityId);
CalculatedFieldEntity findByEntityIdAndName(UUID entityId, String name);
CalculatedFieldEntity findByEntityIdAndTypeAndName(UUID entityId, CalculatedFieldType type, String name);
List<CalculatedFieldId> findCalculatedFieldIdsByTenantIdAndEntityId(UUID tenantId, UUID entityId);

4
dao/src/main/java/org/thingsboard/server/dao/sql/cf/JpaCalculatedFieldDao.java

@ -68,8 +68,8 @@ public class JpaCalculatedFieldDao extends JpaAbstractDao<CalculatedFieldEntity,
}
@Override
public CalculatedField findByEntityIdAndName(EntityId entityId, String name) {
return DaoUtil.getData(calculatedFieldRepository.findByEntityIdAndName(entityId.getId(), name));
public CalculatedField findByEntityIdAndTypeAndName(EntityId entityId, CalculatedFieldType type, String name) {
return DaoUtil.getData(calculatedFieldRepository.findByEntityIdAndTypeAndName(entityId.getId(), type, name));
}
@Override

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

@ -923,7 +923,7 @@ CREATE TABLE IF NOT EXISTS calculated_field (
configuration varchar(1000000),
version BIGINT DEFAULT 1,
debug_settings varchar(1024),
CONSTRAINT calculated_field_unq_key UNIQUE (entity_id, name)
CONSTRAINT calculated_field_unq_key UNIQUE (entity_id, type, name)
);
CREATE TABLE IF NOT EXISTS calculated_field_link (

2
dao/src/test/java/org/thingsboard/server/dao/service/CalculatedFieldServiceTest.java

@ -249,7 +249,7 @@ public class CalculatedFieldServiceTest extends AbstractServiceTest {
assertThatThrownBy(() -> calculatedFieldService.save(calculatedField))
.isInstanceOf(DataValidationException.class)
.hasMessage("Calculated Field with such name is already in exists!");
.hasMessage("Calculated field with such name and type already exists");
}
@Test

Loading…
Cancel
Save