Merge pull request #5351 from ViacheslavKlimov/fix/rule-chains-import
Rule chains import refactoring
This commit is contained in:
commit
96d20b073b
@ -25,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@ -450,15 +449,17 @@ public class RuleChainController extends BaseController {
|
|||||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||||
@RequestMapping(value = "/ruleChains/import", method = RequestMethod.POST)
|
@RequestMapping(value = "/ruleChains/import", method = RequestMethod.POST)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public void importRuleChains(@RequestBody RuleChainData ruleChainData, @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException {
|
public List<RuleChainImportResult> importRuleChains(@RequestBody RuleChainData ruleChainData, @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException {
|
||||||
try {
|
try {
|
||||||
TenantId tenantId = getCurrentUser().getTenantId();
|
TenantId tenantId = getCurrentUser().getTenantId();
|
||||||
List<RuleChainImportResult> importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, RuleChainType.CORE, overwrite);
|
List<RuleChainImportResult> importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite);
|
||||||
if (!CollectionUtils.isEmpty(importResults)) {
|
for (RuleChainImportResult importResult : importResults) {
|
||||||
for (RuleChainImportResult importResult : importResults) {
|
if (importResult.getError() == null) {
|
||||||
tbClusterService.broadcastEntityStateChangeEvent(importResult.getTenantId(), importResult.getRuleChainId(), importResult.getLifecycleEvent());
|
tbClusterService.broadcastEntityStateChangeEvent(importResult.getTenantId(), importResult.getRuleChainId(),
|
||||||
|
importResult.isUpdated() ? ComponentLifecycleEvent.UPDATED : ComponentLifecycleEvent.CREATED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return importResults;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw handleException(e);
|
throw handleException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.id.RuleNodeId;
|
|||||||
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.page.TimePageLink;
|
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChainData;
|
import org.thingsboard.server.common.data.rule.RuleChainData;
|
||||||
@ -71,7 +70,7 @@ public interface RuleChainService {
|
|||||||
|
|
||||||
RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) throws ThingsboardException;
|
RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) throws ThingsboardException;
|
||||||
|
|
||||||
List<RuleChainImportResult> importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, RuleChainType type, boolean overwrite);
|
List<RuleChainImportResult> importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite);
|
||||||
|
|
||||||
RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId);
|
RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId);
|
||||||
|
|
||||||
|
|||||||
@ -15,17 +15,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.common.data.rule;
|
package org.thingsboard.server.common.data.rule;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
|
||||||
public class RuleChainImportResult {
|
public class RuleChainImportResult {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
private TenantId tenantId;
|
private TenantId tenantId;
|
||||||
private RuleChainId ruleChainId;
|
private RuleChainId ruleChainId;
|
||||||
private ComponentLifecycleEvent lifecycleEvent;
|
private String ruleChainName;
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||||
|
private boolean updated;
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
private String error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
@ -38,7 +39,6 @@ import org.thingsboard.server.common.data.id.RuleNodeId;
|
|||||||
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.plugin.ComponentLifecycleEvent;
|
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
import org.thingsboard.server.common.data.rule.NodeConnectionInfo;
|
import org.thingsboard.server.common.data.rule.NodeConnectionInfo;
|
||||||
@ -59,6 +59,7 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
|
|||||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -416,41 +417,46 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RuleChainImportResult> importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, RuleChainType type, boolean overwrite) {
|
public List<RuleChainImportResult> importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite) {
|
||||||
List<RuleChainImportResult> importResults = new ArrayList<>();
|
List<RuleChainImportResult> importResults = new ArrayList<>();
|
||||||
|
|
||||||
setRandomRuleChainIds(ruleChainData);
|
setRandomRuleChainIds(ruleChainData);
|
||||||
resetRuleNodeIds(ruleChainData.getMetadata());
|
resetRuleNodeIds(ruleChainData.getMetadata());
|
||||||
resetRuleChainMetadataTenantIds(tenantId, ruleChainData.getMetadata());
|
resetRuleChainMetadataTenantIds(tenantId, ruleChainData.getMetadata());
|
||||||
if (overwrite) {
|
|
||||||
List<RuleChain> persistentRuleChains = findAllTenantRuleChains(tenantId, type);
|
for (RuleChain ruleChain : ruleChainData.getRuleChains()) {
|
||||||
for (RuleChain ruleChain : ruleChainData.getRuleChains()) {
|
RuleChainImportResult importResult = new RuleChainImportResult();
|
||||||
ComponentLifecycleEvent lifecycleEvent;
|
|
||||||
Optional<RuleChain> persistentRuleChainOpt = persistentRuleChains.stream().filter(rc -> rc.getName().equals(ruleChain.getName())).findFirst();
|
ruleChain.setTenantId(tenantId);
|
||||||
if (persistentRuleChainOpt.isPresent()) {
|
ruleChain.setRoot(false);
|
||||||
setNewRuleChainId(ruleChain, ruleChainData.getMetadata(), ruleChain.getId(), persistentRuleChainOpt.get().getId());
|
|
||||||
ruleChain.setRoot(persistentRuleChainOpt.get().isRoot());
|
if (overwrite) {
|
||||||
lifecycleEvent = ComponentLifecycleEvent.UPDATED;
|
Collection<RuleChain> existingRuleChains = ruleChainDao.findByTenantIdAndTypeAndName(tenantId,
|
||||||
} else {
|
Optional.ofNullable(ruleChain.getType()).orElse(RuleChainType.CORE), ruleChain.getName());
|
||||||
ruleChain.setRoot(false);
|
Optional<RuleChain> existingRuleChain = existingRuleChains.stream().findFirst();
|
||||||
lifecycleEvent = ComponentLifecycleEvent.CREATED;
|
if (existingRuleChain.isPresent()) {
|
||||||
|
setNewRuleChainId(ruleChain, ruleChainData.getMetadata(), ruleChain.getId(), existingRuleChain.get().getId());
|
||||||
|
ruleChain.setRoot(existingRuleChain.get().isRoot());
|
||||||
|
importResult.setUpdated(true);
|
||||||
}
|
}
|
||||||
ruleChain.setTenantId(tenantId);
|
|
||||||
ruleChainDao.save(tenantId, ruleChain);
|
|
||||||
importResults.add(new RuleChainImportResult(tenantId, ruleChain.getId(), lifecycleEvent));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!CollectionUtils.isEmpty(ruleChainData.getRuleChains())) {
|
try {
|
||||||
ruleChainData.getRuleChains().forEach(rc -> {
|
ruleChain = saveRuleChain(ruleChain);
|
||||||
rc.setTenantId(tenantId);
|
} catch (Exception e) {
|
||||||
rc.setRoot(false);
|
importResult.setError(ExceptionUtils.getRootCauseMessage(e));
|
||||||
RuleChain savedRc = ruleChainDao.save(tenantId, rc);
|
|
||||||
importResults.add(new RuleChainImportResult(tenantId, savedRc.getId(), ComponentLifecycleEvent.CREATED));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
importResult.setTenantId(tenantId);
|
||||||
|
importResult.setRuleChainId(ruleChain.getId());
|
||||||
|
importResult.setRuleChainName(ruleChain.getName());
|
||||||
|
importResults.add(importResult);
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(ruleChainData.getMetadata())) {
|
|
||||||
|
if (CollectionUtils.isNotEmpty(ruleChainData.getMetadata())) {
|
||||||
ruleChainData.getMetadata().forEach(md -> saveRuleChainMetaData(tenantId, md));
|
ruleChainData.getMetadata().forEach(md -> saveRuleChainMetaData(tenantId, md));
|
||||||
}
|
}
|
||||||
|
|
||||||
return importResults;
|
return importResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +481,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
|||||||
}
|
}
|
||||||
if (isTenantId) {
|
if (isTenantId) {
|
||||||
ObjectNode objNode = (ObjectNode) node;
|
ObjectNode objNode = (ObjectNode) node;
|
||||||
objNode.put("id", tenantId.getId().toString());
|
if (objNode.has("id")) {
|
||||||
|
objNode.put("id", tenantId.getId().toString());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (JsonNode jsonNode : node) {
|
for (JsonNode jsonNode : node) {
|
||||||
searchTenantIdRecursive(tenantId, jsonNode);
|
searchTenantIdRecursive(tenantId, jsonNode);
|
||||||
@ -723,4 +731,5 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
|||||||
checkRuleNodesAndDelete(tenantId, entity.getId());
|
checkRuleNodesAndDelete(tenantId, entity.getId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.rule;
|
package org.thingsboard.server.dao.rule;
|
||||||
|
|
||||||
|
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.rule.RuleChain;
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
@ -22,6 +23,7 @@ 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.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,4 +76,7 @@ public interface RuleChainDao extends Dao<RuleChain>, TenantEntityDao {
|
|||||||
* @return the list of rule chain objects
|
* @return the list of rule chain objects
|
||||||
*/
|
*/
|
||||||
PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink);
|
PageData<RuleChain> findAutoAssignToEdgeRuleChainsByTenantId(UUID tenantId, PageLink pageLink);
|
||||||
|
|
||||||
|
Collection<RuleChain> findByTenantIdAndTypeAndName(TenantId tenantId, RuleChainType type, String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import org.thingsboard.server.dao.model.sql.RuleChainEntity;
|
|||||||
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.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -97,8 +98,14 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
|
|||||||
DaoUtil.toPageable(pageLink)));
|
DaoUtil.toPageable(pageLink)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<RuleChain> findByTenantIdAndTypeAndName(TenantId tenantId, RuleChainType type, String name) {
|
||||||
|
return DaoUtil.convertDataList(ruleChainRepository.findByTenantIdAndTypeAndName(tenantId.getId(), type, name));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long countByTenantId(TenantId tenantId) {
|
public Long countByTenantId(TenantId tenantId) {
|
||||||
return ruleChainRepository.countByTenantId(tenantId.getId());
|
return ruleChainRepository.countByTenantId(tenantId.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ 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.RuleChainEntity;
|
import org.thingsboard.server.dao.model.sql.RuleChainEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface RuleChainRepository extends PagingAndSortingRepository<RuleChainEntity, UUID> {
|
public interface RuleChainRepository extends PagingAndSortingRepository<RuleChainEntity, UUID> {
|
||||||
@ -55,10 +56,13 @@ public interface RuleChainRepository extends PagingAndSortingRepository<RuleChai
|
|||||||
"AND re.relationType = 'Contains' AND re.fromId = :tenantId AND re.fromType = 'TENANT' " +
|
"AND re.relationType = 'Contains' AND re.fromId = :tenantId AND re.fromType = 'TENANT' " +
|
||||||
"AND LOWER(rc.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
|
"AND LOWER(rc.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
|
||||||
Page<RuleChainEntity> findAutoAssignByTenantId(@Param("tenantId") UUID tenantId,
|
Page<RuleChainEntity> findAutoAssignByTenantId(@Param("tenantId") UUID tenantId,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType);
|
RuleChainEntity findByTenantIdAndTypeAndRootIsTrue(UUID tenantId, RuleChainType ruleChainType);
|
||||||
|
|
||||||
Long countByTenantId(UUID tenantId);
|
Long countByTenantId(UUID tenantId);
|
||||||
|
|
||||||
|
List<RuleChainEntity> findByTenantIdAndTypeAndName(UUID tenantId, RuleChainType type, String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user