Browse Source

Multiple names filter for CF

pull/14328/head
Viacheslav Klimov 7 months ago
parent
commit
524488bd3e
  1. 10
      application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
  2. 21
      application/src/test/java/org/thingsboard/server/controller/CalculatedFieldControllerTest.java
  3. 2
      common/data/src/main/java/org/thingsboard/server/common/data/cf/CalculatedFieldFilter.java
  4. 2
      dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java
  5. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/cf/CalculatedFieldRepository.java
  6. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/cf/JpaCalculatedFieldDao.java

10
application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java

@ -25,6 +25,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@ -203,14 +204,15 @@ public class CalculatedFieldController extends BaseController {
@RequestParam(required = false) EntityType entityType,
@Parameter(description = "Entities filter. If not specified, calculated fields for entity type filter will be returned.")
@RequestParam(required = false) List<UUID> entities,
@Parameter(description = "Name filter.")
@RequestParam(required = false) String name,
@Parameter(description = "Name filter. To specify multiple names, duplicate 'name' parameter for each name, for example '?name=name1&name=name2")
@RequestParam(required = false) String name, // for Swagger only, retrieved from MultiValueMap params (due to issues when name contains comma)
@Parameter(description = CF_TEXT_SEARCH_DESCRIPTION)
@RequestParam(required = false) String textSearch,
@Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name"}))
@RequestParam(required = false) String sortProperty,
@Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}))
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
@RequestParam(required = false) String sortOrder,
@RequestParam MultiValueMap<String, String> params) throws ThingsboardException {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
SecurityUser user = getCurrentUser();
Set<EntityType> entityTypes;
@ -224,7 +226,7 @@ public class CalculatedFieldController extends BaseController {
.type(type)
.entityTypes(entityTypes)
.entityIds(entities)
.name(name)
.names(params.get("name"))
.build();
return calculatedFieldService.findCalculatedFieldsByTenantIdAndFilter(user.getTenantId(), filter, pageLink);
}

21
application/src/test/java/org/thingsboard/server/controller/CalculatedFieldControllerTest.java

@ -51,6 +51,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
@ -223,28 +224,36 @@ public class CalculatedFieldControllerTest extends AbstractControllerTest {
"Profile A"
);
List<CalculatedFieldInfo> allCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE, null, null, null);
List<CalculatedFieldInfo> allCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE,
null, null, null);
assertThat(allCalculatedFields).contains(deviceCalculatedField, profileCalculatedField);
List<CalculatedFieldInfo> profileLevelCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE, EntityType.DEVICE_PROFILE, null, null);
List<CalculatedFieldInfo> profileLevelCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE,
EntityType.DEVICE_PROFILE, null, null);
assertThat(profileLevelCalculatedFields).containsOnly(profileCalculatedField);
List<CalculatedFieldInfo> specificDeviceCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE, EntityType.DEVICE, List.of(device.getUuidId()), null);
List<CalculatedFieldInfo> specificDeviceCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE,
EntityType.DEVICE, List.of(device.getUuidId()), null);
assertThat(specificDeviceCalculatedFields).containsOnly(deviceCalculatedField);
List<CalculatedFieldInfo> byNameCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE, null, null, deviceCalculatedField.getName());
List<CalculatedFieldInfo> byNameCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE,
null, null, List.of(deviceCalculatedField.getName()));
assertThat(byNameCalculatedFields).containsOnly(deviceCalculatedField);
byNameCalculatedFields = getCalculatedFields(CalculatedFieldType.SIMPLE, null, null,
List.of(deviceCalculatedField.getName(), profileCalculatedField.getName()));
assertThat(byNameCalculatedFields).contains(deviceCalculatedField, profileCalculatedField);
}
private List<CalculatedFieldInfo> getCalculatedFields(CalculatedFieldType type,
EntityType entityType,
List<UUID> entities,
String name) throws Exception {
List<String> names) throws Exception {
return doGetTypedWithPageLink("/api/calculatedFields?type=" + type + "&" +
(entityType != null ? "entityType=" + entityType + "&" : "") +
(entities != null ? "entities=" + String.join(",",
entities.stream().map(UUID::toString).toList()) + "&" : "") +
(name != null ? "name=" + name + "&" : ""),
(names != null ? names.stream().map(name -> "name=" + name + "&").collect(Collectors.joining("")) : ""),
new TypeReference<PageData<CalculatedFieldInfo>>() {}, new PageLink(10)).getData();
}

2
common/data/src/main/java/org/thingsboard/server/common/data/cf/CalculatedFieldFilter.java

@ -36,6 +36,6 @@ public class CalculatedFieldFilter {
@Nullable
private final List<UUID> entityIds;
@Nullable
private final String name;
private final List<String> names;
}

2
dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java

@ -93,7 +93,7 @@ public abstract class DataValidator<D extends BaseData<?>> {
}
public void validateString(String exceptionPrefix, String name) {
if (StringUtils.isEmpty(name) || name.trim().length() == 0) {
if (StringUtils.isBlank(name)) {
throw new DataValidationException(exceptionPrefix + " should be specified!");
}
if (StringUtils.contains0x00(name)) {

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

@ -46,10 +46,10 @@ public interface CalculatedFieldRepository extends JpaRepository<CalculatedField
"AND cf.type = :type " +
"AND cf.entityType IN :entityTypes " +
"AND (:entityIds IS NULL OR cf.entityId IN :entityIds) " +
"AND (:name IS NULL OR cf.name = :name) " +
"AND (:names IS NULL OR cf.name IN :names) " +
"AND (:textSearch IS NULL OR ilike(cf.name, CONCAT('%', :textSearch, '%')) = true)")
Page<CalculatedFieldEntity> findByTenantIdAndFilter(UUID tenantId, String type, List<String> entityTypes,
List<UUID> entityIds, String name, String textSearch, Pageable pageable);
List<UUID> entityIds, List<String> names, String textSearch, Pageable pageable);
List<CalculatedFieldEntity> findAllByTenantId(UUID tenantId);

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

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.dao.sql.cf;
import com.google.common.base.Strings;
import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -110,7 +109,7 @@ public class JpaCalculatedFieldDao extends JpaAbstractDao<CalculatedFieldEntity,
return DaoUtil.toPageData(calculatedFieldRepository.findByTenantIdAndFilter(tenantId.getId(), filter.getType().name(),
filter.getEntityTypes().stream().map(Enum::name).toList(),
CollectionUtils.isNotEmpty(filter.getEntityIds()) ? filter.getEntityIds() : null,
Strings.emptyToNull(filter.getName()),
CollectionUtils.isNotEmpty(filter.getNames()) ? filter.getNames() : null,
pageLink.getTextSearch(), DaoUtil.toPageable(pageLink)));
}

Loading…
Cancel
Save