Refactored DAO to remove additional call to relation table - use spring query

This commit is contained in:
Volodymyr Babak 2021-05-13 15:04:12 +03:00
parent 96ed8f1691
commit 71791c6847
8 changed files with 51 additions and 56 deletions

View File

@ -70,6 +70,7 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -85,6 +86,8 @@ public class RuleChainController extends BaseController {
public static final String RULE_CHAIN_ID = "ruleChainId"; public static final String RULE_CHAIN_ID = "ruleChainId";
public static final String RULE_NODE_ID = "ruleNodeId"; public static final String RULE_NODE_ID = "ruleNodeId";
private static final int DEFAULT_LIMIT = 100;
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
@Autowired @Autowired
@ -477,7 +480,7 @@ public class RuleChainController extends BaseController {
return objectMapper.writeValueAsString(resultNode); return objectMapper.writeValueAsString(resultNode);
} }
private JsonNode convertMsgToOut(TbMsg msg) throws Exception{ private JsonNode convertMsgToOut(TbMsg msg) throws Exception {
ObjectNode msgData = objectMapper.createObjectNode(); ObjectNode msgData = objectMapper.createObjectNode();
if (!StringUtils.isEmpty(msg.getData())) { if (!StringUtils.isEmpty(msg.getData())) {
msgData.set("msg", objectMapper.readTree(msg.getData())); msgData.set("msg", objectMapper.readTree(msg.getData()));
@ -632,13 +635,26 @@ public class RuleChainController extends BaseController {
} }
} }
// TODO: refactor this - add new config to edge rule chain to set it as auto-assign
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/ruleChain/autoAssignToEdgeRuleChains", method = RequestMethod.GET) @RequestMapping(value = "/ruleChain/autoAssignToEdgeRuleChains", method = RequestMethod.GET)
@ResponseBody @ResponseBody
public List<RuleChain> getAutoAssignToEdgeRuleChains() throws ThingsboardException { public List<RuleChain> getAutoAssignToEdgeRuleChains() throws ThingsboardException {
try { try {
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId)).get(); List<RuleChain> result = new ArrayList<>();
PageLink pageLink = new PageLink(DEFAULT_LIMIT);
PageData<RuleChain> pageData;
do {
pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink);
if (pageData.getData().size() > 0) {
result.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
}
} while (pageData.hasNext());
return checkNotNull(result);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

View File

@ -87,6 +87,6 @@ public interface RuleChainService {
boolean unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId); boolean unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChainId ruleChainId);
ListenableFuture<List<RuleChain>> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId); PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId, PageLink pageLink);
} }

View File

@ -19,7 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
@ -381,22 +380,19 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
@Override @Override
public void assignDefaultRuleChainsToEdge(TenantId tenantId, EdgeId edgeId) { public void assignDefaultRuleChainsToEdge(TenantId tenantId, EdgeId edgeId) {
log.trace("Executing assignDefaultRuleChainsToEdge, tenantId [{}], edgeId [{}]", tenantId, edgeId); log.trace("Executing assignDefaultRuleChainsToEdge, tenantId [{}], edgeId [{}]", tenantId, edgeId);
ListenableFuture<List<RuleChain>> future = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId); PageLink pageLink = new PageLink(DEFAULT_LIMIT);
Futures.addCallback(future, new FutureCallback<List<RuleChain>>() { PageData<RuleChain> pageData;
@Override do {
public void onSuccess(List<RuleChain> ruleChains) { pageData = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, pageLink);
if (ruleChains != null && !ruleChains.isEmpty()) { if (pageData.getData().size() > 0) {
for (RuleChain ruleChain : ruleChains) { for (RuleChain ruleChain : pageData.getData()) {
ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), edgeId); ruleChainService.assignRuleChainToEdge(tenantId, ruleChain.getId(), edgeId);
}
} }
} }
if (pageData.hasNext()) {
@Override pageLink = pageLink.nextPageLink();
public void onFailure(Throwable t) {
log.warn("[{}] can't find default edge rule chains [{}]", tenantId.getId(), edgeId.getId(), t);
} }
}, MoreExecutors.directExecutor()); } while (pageData.hasNext());
} }
@Override @Override

View File

@ -631,13 +631,12 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
} }
@Override @Override
public ListenableFuture<List<RuleChain>> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId) { public PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findAutoAssignToEdgeRuleChainsByTenantId, tenantId [{}]", tenantId); log.trace("Executing findAutoAssignToEdgeRuleChainsByTenantId, tenantId [{}], pageLink {}", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return ruleChainDao.findAutoAssignToEdgeRuleChainsByTenantId(tenantId.getId()); return ruleChainDao.findAutoAssignToEdgeRuleChainsByTenantId(tenantId.getId(), pageLink);
} }
private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) { private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) {
try{ try{
ruleChainDao.removeById(tenantId, ruleChainId.getId()); ruleChainDao.removeById(tenantId, ruleChainId.getId());

View File

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.dao.rule; package org.thingsboard.server.dao.rule;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
@ -23,7 +22,6 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.Dao; import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.TenantEntityDao; import org.thingsboard.server.dao.TenantEntityDao;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -75,5 +73,5 @@ public interface RuleChainDao extends Dao<RuleChain>, TenantEntityDao {
* @param tenantId the tenantId * @param tenantId the tenantId
* @return the list of rule chain objects * @return the list of rule chain objects
*/ */
ListenableFuture<List<RuleChain>> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId); PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink);
} }

View File

@ -15,9 +15,6 @@
*/ */
package org.thingsboard.server.dao.sql.rule; package org.thingsboard.server.dao.sql.rule;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
@ -25,19 +22,13 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.sql.RuleChainEntity; import org.thingsboard.server.dao.model.sql.RuleChainEntity;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.rule.RuleChainDao; import org.thingsboard.server.dao.rule.RuleChainDao;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -48,9 +39,6 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
@Autowired @Autowired
private RuleChainRepository ruleChainRepository; private RuleChainRepository ruleChainRepository;
@Autowired
private RelationDao relationDao;
@Override @Override
protected Class<RuleChainEntity> getEntityClass() { protected Class<RuleChainEntity> getEntityClass() {
return RuleChainEntity.class; return RuleChainEntity.class;
@ -91,7 +79,6 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
@Override @Override
public PageData<RuleChain> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, PageLink pageLink) { public PageData<RuleChain> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, PageLink pageLink) {
log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink); log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
return DaoUtil.toPageData(ruleChainRepository return DaoUtil.toPageData(ruleChainRepository
.findByTenantIdAndEdgeId( .findByTenantIdAndEdgeId(
tenantId, tenantId,
@ -101,21 +88,13 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
} }
@Override @Override
public ListenableFuture<List<RuleChain>> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId) { public PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink) {
log.debug("Try to find auto assign to edge rule chains by tenantId [{}]", tenantId); log.debug("Try to find auto assign to edge rule chains by tenantId [{}]", tenantId);
ListenableFuture<List<EntityRelation>> relations = return DaoUtil.toPageData(ruleChainRepository
relationDao.findAllByFromAndType(new TenantId(tenantId), new TenantId(tenantId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE_AUTO_ASSIGN_RULE_CHAIN); .findAutoAssignByTenantId(
return Futures.transformAsync(relations, input -> { tenantId,
if (input != null && !input.isEmpty()) { Objects.toString(pageLink.getTextSearch(), ""),
List<ListenableFuture<RuleChain>> ruleChainsFutures = new ArrayList<>(input.size()); DaoUtil.toPageable(pageLink)));
for (EntityRelation relation : input) {
ruleChainsFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(ruleChainsFutures);
} else {
return Futures.immediateFuture(Collections.emptyList());
}
}, MoreExecutors.directExecutor());
} }
@Override @Override

View File

@ -21,7 +21,6 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.model.sql.DashboardInfoEntity;
import org.thingsboard.server.dao.model.sql.RuleChainEntity; import org.thingsboard.server.dao.model.sql.RuleChainEntity;
import java.util.UUID; import java.util.UUID;
@ -51,6 +50,14 @@ public interface RuleChainRepository extends PagingAndSortingRepository<RuleChai
@Param("searchText") String searchText, @Param("searchText") String searchText,
Pageable pageable); Pageable pageable);
@Query("SELECT rc FROM RuleChainEntity rc, RelationEntity re WHERE rc.tenantId = :tenantId " +
"AND rc.id = re.toId AND re.toType = 'RULE_CHAIN' AND re.relationTypeGroup = 'EDGE_AUTO_ASSIGN_RULE_CHAIN' " +
"AND re.relationType = 'Contains' AND re.fromId = :tenantId AND re.fromType = 'TENANT' " +
"AND LOWER(rc.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
Page<RuleChainEntity> findAutoAssignByTenantId(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText,
Pageable pageable);
RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType); RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType);
Long countByTenantId(UUID tenantId); Long countByTenantId(UUID tenantId);

View File

@ -334,13 +334,13 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
public void testGetDefaultEdgeRuleChains() throws Exception { public void testGetDefaultEdgeRuleChains() throws Exception {
RuleChainId ruleChainId = saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 1"); RuleChainId ruleChainId = saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 1");
saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 2"); saveRuleChainAndSetAutoAssignToEdge("Default Edge Rule Chain 2");
List<RuleChain> result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId).get(); PageData<RuleChain> result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, new PageLink(100));
Assert.assertEquals(2, result.size()); Assert.assertEquals(2, result.getData().size());
ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId); ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId);
result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId).get(); result = ruleChainService.findAutoAssignToEdgeRuleChainsByTenantId(tenantId, new PageLink(100));
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.getData().size());
} }
@Test @Test