Browse Source

Entities import/export for CE

pull/6758/head
Andrii Shvaika 4 years ago
parent
commit
fa5335130b
  1. 6
      application/src/main/data/upgrade/3.3.4/schema_update.sql
  2. 9
      application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/RuleChainExportService.java
  3. 3
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DashboardImportService.java
  4. 7
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceProfileImportService.java
  5. 55
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java
  6. 2
      application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesExportCtx.java
  7. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/relation/RelationService.java
  8. 4
      common/data/src/main/java/org/thingsboard/server/common/data/BaseData.java
  9. 35
      common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
  10. 3
      common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java
  11. 9
      dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java
  12. 40
      dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java
  13. 2
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  14. 3
      dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java
  15. 1
      dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java
  16. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/EntityAlarmRepository.java
  17. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/component/ComponentDescriptorRepository.java
  18. 17
      dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
  19. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java
  20. 13
      dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java
  21. 1
      dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java
  22. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/usagerecord/ApiUsageStateRepository.java
  23. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/user/UserAuthSettingsRepository.java
  24. 4
      dao/src/main/resources/sql/schema-entities-idx.sql
  25. 3
      dao/src/main/resources/sql/schema-entities.sql
  26. 2
      dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java

6
application/src/main/data/upgrade/3.3.4/schema_update.sql

@ -22,6 +22,8 @@ ALTER TABLE asset
ADD COLUMN IF NOT EXISTS external_id UUID;
ALTER TABLE rule_chain
ADD COLUMN IF NOT EXISTS external_id UUID;
ALTER TABLE rule_node
ADD COLUMN IF NOT EXISTS external_id UUID;
ALTER TABLE dashboard
ADD COLUMN IF NOT EXISTS external_id UUID;
ALTER TABLE customer
@ -35,11 +37,14 @@ CREATE INDEX IF NOT EXISTS idx_device_external_id ON device(tenant_id, external_
CREATE INDEX IF NOT EXISTS idx_device_profile_external_id ON device_profile(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_asset_external_id ON asset(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_rule_chain_external_id ON rule_chain(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, external_id);
CREATE INDEX IF NOT EXISTS idx_dashboard_external_id ON dashboard(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_customer_external_id ON customer(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_widgets_bundle_external_id ON widgets_bundle(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_entity_view_external_id ON entity_view(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type);
ALTER TABLE admin_settings
ADD COLUMN IF NOT EXISTS tenant_id uuid NOT NULL DEFAULT '13814000-1dd2-11b2-8080-808080808080';
@ -64,3 +69,4 @@ CREATE TABLE IF NOT EXISTS user_auth_settings (
user_id uuid UNIQUE NOT NULL CONSTRAINT fk_user_auth_settings_user_id REFERENCES tb_user(id),
two_fa_settings varchar
);

9
application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/RuleChainExportService.java

@ -22,8 +22,8 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx;
@ -47,6 +47,10 @@ public class RuleChainExportService extends BaseEntityExportService<RuleChainId,
Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList())
.forEach(ruleNode -> {
ruleNode.setRuleChainId(null);
ctx.putExternalId(ruleNode.getId(), ruleNode.getExternalId());
ruleNode.setId(ctx.getExternalId(ruleNode.getId()));
ruleNode.setCreatedTime(0);
ruleNode.setExternalId(null);
JsonNode ruleNodeConfig = ruleNode.getConfiguration();
String newRuleNodeConfigJson = RegexUtils.replace(ruleNodeConfig.toString(), RegexUtils.UUID_PATTERN, uuid -> {
return getExternalIdOrElseInternalByUuid(ctx, UUID.fromString(uuid)).toString();
@ -59,6 +63,9 @@ public class RuleChainExportService extends BaseEntityExportService<RuleChainId,
ruleChainConnectionInfo.setTargetRuleChainId(getExternalIdOrElseInternal(ctx, ruleChainConnectionInfo.getTargetRuleChainId()));
});
exportData.setMetaData(metaData);
if (ruleChain.getFirstRuleNodeId() != null) {
ruleChain.setFirstRuleNodeId(ctx.getExternalId(ruleChain.getFirstRuleNodeId()));
}
}
@Override

3
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DashboardImportService.java

@ -100,7 +100,7 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
.collect(Collectors.toSet());
if (dashboard.getId() == null) {
dashboard.setAssignedCustomers(null);
dashboard.setAssignedCustomers(assignedCustomers);
dashboard = dashboardService.saveDashboard(dashboard);
for (ShortCustomerInfo customerInfo : assignedCustomers) {
dashboard = dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerInfo.getCustomerId());
@ -121,7 +121,6 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
for (CustomerId customerId : toAssign) {
assignedCustomers = dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerId).getAssignedCustomers();
}
dashboard.setAssignedCustomers(assignedCustomers);
dashboard = dashboardService.saveDashboard(dashboard);
}

7
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceProfileImportService.java

@ -78,6 +78,13 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
return new DeviceProfile(deviceProfile);
}
@Override
protected void cleanupForComparison(DeviceProfile deviceProfile) {
super.cleanupForComparison(deviceProfile);
deviceProfile.setFirmwareId(null);
deviceProfile.setSoftwareId(null);
}
@Override
public EntityType getEntityType() {
return EntityType.DEVICE_PROFILE;

55
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java

@ -24,13 +24,16 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.data.sync.ie.RuleChainExportData;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.rule.RuleNodeDao;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
@ -39,8 +42,10 @@ import org.thingsboard.server.utils.RegexUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -51,6 +56,7 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
private static final LinkedHashSet<EntityType> HINTS = new LinkedHashSet<>(Arrays.asList(EntityType.RULE_CHAIN, EntityType.DEVICE, EntityType.ASSET));
private final RuleChainService ruleChainService;
private final RuleNodeDao ruleNodeDao;
@Override
protected void setOwner(TenantId tenantId, RuleChain ruleChain, IdProvider idProvider) {
@ -69,26 +75,44 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
@Override
protected RuleChain prepare(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChain old, RuleChainExportData exportData, IdProvider idProvider) {
RuleChainMetaData metaData = exportData.getMetaData();
Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList())
.forEach(ruleNode -> {
ruleNode.setId(null);
ruleNode.setRuleChainId(null);
List<RuleNode> ruleNodes = Optional.ofNullable(metaData.getNodes()).orElse(Collections.emptyList());
if (old != null) {
// boolean original = old.getId().equals(old.getExternalId());
List<RuleNodeId> nodeIds = ruleNodes.stream().map(RuleNode::getId).collect(Collectors.toList());
List<RuleNode> existing = ruleNodeDao.findByExternalIds(old.getId(), nodeIds);
existing.forEach(node -> ctx.putInternalId(node.getExternalId(), node.getId()));
ruleNodes.forEach(node -> {
node.setRuleChainId(old.getId());
// if (!original) {
node.setExternalId(node.getId());
// }
node.setId((RuleNodeId) ctx.getInternalId(node.getId()));
});
} else {
ruleNodes.forEach(node -> {
node.setRuleChainId(null);
node.setExternalId(node.getId());
node.setId(null);
});
}
JsonNode ruleNodeConfig = ruleNode.getConfiguration();
String newRuleNodeConfigJson = RegexUtils.replace(ruleNodeConfig.toString(), RegexUtils.UUID_PATTERN, uuid -> {
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFetchAllUUIDs(), HINTS)
.map(entityId -> entityId.getId().toString())
.orElse(uuid);
});
ruleNodeConfig = JacksonUtil.toJsonNode(newRuleNodeConfigJson);
ruleNode.setConfiguration(ruleNodeConfig);
});
ruleNodes.forEach(ruleNode -> {
JsonNode ruleNodeConfig = ruleNode.getConfiguration();
String newRuleNodeConfigJson = RegexUtils.replace(ruleNodeConfig.toString(), RegexUtils.UUID_PATTERN, uuid -> {
return idProvider.getInternalIdByUuid(UUID.fromString(uuid), ctx.isFetchAllUUIDs(), HINTS)
.map(entityId -> entityId.getId().toString())
.orElse(uuid);
});
ruleNodeConfig = JacksonUtil.toJsonNode(newRuleNodeConfigJson);
ruleNode.setConfiguration(ruleNodeConfig);
});
Optional.ofNullable(metaData.getRuleChainConnections()).orElse(Collections.emptyList())
.forEach(ruleChainConnectionInfo -> {
ruleChainConnectionInfo.setTargetRuleChainId(idProvider.getInternalId(ruleChainConnectionInfo.getTargetRuleChainId(), false));
});
//TODO: lookup rule node id based on external rule node id.
ruleChain.setFirstRuleNodeId(null);
if (ruleChain.getFirstRuleNodeId() != null) {
ruleChain.setFirstRuleNodeId((RuleNodeId) ctx.getInternalId(ruleChain.getFirstRuleNodeId()));
}
return ruleChain;
}
@ -106,6 +130,7 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
if (!different) {
RuleChainMetaData newMD = exportData.getMetaData();
RuleChainMetaData existingMD = ruleChainService.loadRuleChainMetaData(ctx.getTenantId(), prepared.getId());
existingMD.setRuleChainId(null);
different = newMD.equals(existingMD);
}
return different;

2
application/src/main/java/org/thingsboard/server/service/sync/vc/data/EntitiesExportCtx.java

@ -83,6 +83,6 @@ public abstract class EntitiesExportCtx<R extends VersionCreateRequest> {
public void putExternalId(EntityId internalId, EntityId externalId) {
log.debug("[{}][{}] Local cache put: {}", internalId.getEntityType(), internalId.getId(), externalId);
externalIdMap.put(internalId, externalId);
externalIdMap.put(internalId, externalId != null ? externalId : internalId);
}
}

2
common/dao-api/src/main/java/org/thingsboard/server/dao/relation/RelationService.java

@ -55,8 +55,6 @@ public interface RelationService {
void deleteEntityRelations(TenantId tenantId, EntityId entity);
ListenableFuture<Void> deleteEntityRelationsAsync(TenantId tenantId, EntityId entity);
List<EntityRelation> findByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);
ListenableFuture<List<EntityRelation>> findByFromAsync(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);

4
common/data/src/main/java/org/thingsboard/server/common/data/BaseData.java

@ -65,9 +65,7 @@ public abstract class BaseData<I extends UUIDBased> extends IdBased<I> implement
if (getClass() != obj.getClass())
return false;
BaseData other = (BaseData) obj;
if (createdTime != other.createdTime)
return false;
return true;
return createdTime == other.createdTime;
}
@Override

35
common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java

@ -18,6 +18,7 @@ package org.thingsboard.server.common.data;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
import javax.validation.Valid;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@ApiModel
@ -63,7 +65,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
@ApiModelProperty(position = 1, value = "JSON object with the dashboard Id. " +
"Specify existing dashboard Id to update the dashboard. " +
"Referencing non-existing dashboard id will cause error. " +
"Omit this field to create new dashboard." )
"Omit this field to create new dashboard.")
@Override
public DashboardId getId() {
return super.getId();
@ -133,7 +135,6 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
return this.assignedCustomers != null && this.assignedCustomers.contains(new ShortCustomerInfo(customerId, null, false));
}
public ShortCustomerInfo getAssignedCustomerInfo(CustomerId customerId) {
if (this.assignedCustomers != null) {
for (ShortCustomerInfo customerInfo : this.assignedCustomers) {
@ -201,25 +202,17 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
DashboardInfo other = (DashboardInfo) obj;
if (tenantId == null) {
if (other.tenantId != null)
return false;
} else if (!tenantId.equals(other.tenantId))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
DashboardInfo that = (DashboardInfo) o;
return mobileHide == that.mobileHide
&& Objects.equals(tenantId, that.tenantId)
&& Objects.equals(title, that.title)
&& Objects.equals(image, that.image)
&& Objects.equals(assignedCustomers, that.assignedCustomers)
&& Objects.equals(mobileOrder, that.mobileOrder);
}
@Override

3
common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java

@ -53,6 +53,8 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo<RuleNodeId> impl
@JsonIgnore
private byte[] configurationBytes;
private RuleNodeId externalId;
public RuleNode() {
super();
}
@ -68,6 +70,7 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo<RuleNodeId> impl
this.name = ruleNode.getName();
this.debugMode = ruleNode.isDebugMode();
this.setConfiguration(ruleNode.getConfiguration());
this.externalId = ruleNode.getExternalId();
}
@Override

9
dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java

@ -64,6 +64,9 @@ public class RuleNodeEntity extends BaseSqlEntity<RuleNode> implements SearchTex
@Column(name = ModelConstants.DEBUG_MODE)
private boolean debugMode;
@Column(name = ModelConstants.EXTERNAL_ID_PROPERTY)
private UUID externalId;
public RuleNodeEntity() {
}
@ -81,6 +84,9 @@ public class RuleNodeEntity extends BaseSqlEntity<RuleNode> implements SearchTex
this.searchText = ruleNode.getName();
this.configuration = ruleNode.getConfiguration();
this.additionalInfo = ruleNode.getAdditionalInfo();
if (ruleNode.getExternalId() != null) {
this.externalId = ruleNode.getExternalId().getId();
}
}
@Override
@ -105,6 +111,9 @@ public class RuleNodeEntity extends BaseSqlEntity<RuleNode> implements SearchTex
ruleNode.setDebugMode(debugMode);
ruleNode.setConfiguration(configuration);
ruleNode.setAdditionalInfo(additionalInfo);
if (externalId != null) {
ruleNode.setExternalId(new RuleNodeId(externalId));
}
return ruleNode;
}
}

40
dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java

@ -25,6 +25,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.thingsboard.server.cache.TbTransactionalCache;
@ -180,6 +181,7 @@ public class BaseRelationService implements RelationService {
return future;
}
@Transactional
@Override
public void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityRelations [{}]", entityId);
@ -208,44 +210,6 @@ public class BaseRelationService implements RelationService {
}
}
@Override
public ListenableFuture<Void> deleteEntityRelationsAsync(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityRelationsAsync [{}]", entityId);
validate(entityId);
List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>();
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
inboundRelationsList.add(executor.submit(() -> relationDao.findAllByTo(tenantId, entityId, typeGroup)));
}
ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>();
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
outboundRelationsList.add(executor.submit(() -> relationDao.findAllByFrom(tenantId, entityId, typeGroup)));
}
ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList);
ListenableFuture<List<Boolean>> inboundDeletions = Futures.transformAsync(inboundRelations,
relations -> {
List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, true);
return Futures.allAsList(results);
}, MoreExecutors.directExecutor());
ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations,
relations -> {
List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, false);
return Futures.allAsList(results);
}, MoreExecutors.directExecutor());
ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions);
return Futures.transform(Futures.transformAsync(deletionsFuture,
(deletions) -> relationDao.deleteOutboundRelationsAsync(tenantId, entityId),
MoreExecutors.directExecutor()),
result -> null, MoreExecutors.directExecutor());
}
private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(TenantId tenantId, List<List<EntityRelation>> relations, boolean deleteFromDb) {
List<ListenableFuture<Boolean>> results = new ArrayList<>();
for (List<EntityRelation> relationList : relations) {

2
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -301,6 +301,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
}
}
}
Collections.sort(ruleChainMetaData.getConnections(), Comparator.comparingInt(NodeConnectionInfo::getFromIndex)
.thenComparing(NodeConnectionInfo::getToIndex).thenComparing(NodeConnectionInfo::getType));
return ruleChainMetaData;
}

3
dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.rule;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -33,5 +34,7 @@ public interface RuleNodeDao extends Dao<RuleNode> {
PageData<RuleNode> findAllRuleNodesByType(String type, PageLink pageLink);
List<RuleNode> findByExternalIds(RuleChainId ruleChainId, List<RuleNodeId> externalIds);
void deleteByIdIn(List<RuleNodeId> ruleNodeIds);
}

1
dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java

@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.id.AdminSettingsId;
import org.thingsboard.server.common.data.id.TenantId;

7
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/EntityAlarmRepository.java

@ -16,6 +16,9 @@
package org.thingsboard.server.dao.sql.alarm;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.EntityAlarmCompositeKey;
import org.thingsboard.server.dao.model.sql.EntityAlarmEntity;
@ -28,5 +31,7 @@ public interface EntityAlarmRepository extends JpaRepository<EntityAlarmEntity,
List<EntityAlarmEntity> findAllByAlarmId(UUID alarmId);
@Transactional
void deleteByEntityId(UUID id);
@Modifying
@Query("DELETE FROM EntityAlarmEntity e where e.entityId = :entityId")
void deleteByEntityId(@Param("entityId") UUID entityId);
}

7
dao/src/main/java/org/thingsboard/server/dao/sql/component/ComponentDescriptorRepository.java

@ -18,8 +18,10 @@ package org.thingsboard.server.dao.sql.component;
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.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.plugin.ComponentScope;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
@ -46,5 +48,8 @@ public interface ComponentDescriptorRepository extends JpaRepository<ComponentDe
@Param("textSearch") String textSearch,
Pageable pageable);
void deleteByClazz(String clazz);
@Transactional
@Modifying
@Query("DELETE FROM ComponentDescriptorEntity cd where cd.clazz = :clazz")
void deleteByClazz(@Param("clazz") String clazz);
}

17
dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.sql.relation;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
@ -36,8 +37,8 @@ public interface RelationRepository
String relationTypeGroup);
List<RelationEntity> findAllByFromIdAndFromTypeAndRelationTypeGroupIn(UUID fromId,
String fromType,
List<String> relationTypeGroups);
String fromType,
List<String> relationTypeGroups);
List<RelationEntity> findAllByFromIdAndFromTypeAndRelationTypeAndRelationTypeGroup(UUID fromId,
String fromType,
@ -49,8 +50,8 @@ public interface RelationRepository
String relationTypeGroup);
List<RelationEntity> findAllByToIdAndToTypeAndRelationTypeGroupIn(UUID toId,
String toType,
List<String> relationTypeGroups);
String toType,
List<String> relationTypeGroups);
List<RelationEntity> findAllByToIdAndToTypeAndRelationTypeAndRelationTypeGroup(UUID toId,
String toType,
@ -72,9 +73,13 @@ public interface RelationRepository
void deleteById(RelationCompositeKey id);
@Transactional
void deleteByFromIdAndFromType(UUID fromId, String fromType);
@Modifying
@Query("DELETE FROM RelationEntity r where r.fromId = :fromId and r.fromType = :fromType")
void deleteByFromIdAndFromType(@Param("fromId") UUID fromId, @Param("fromType") String fromType);
@Transactional
void deleteByToIdAndToTypeAndRelationTypeGroupIn(UUID fromId, String fromType, List<String> relationTypeGroups);
@Modifying
@Query("DELETE FROM RelationEntity r where r.toId = :toId and r.toType = :toType and r.relationTypeGroup in :relationTypeGroups")
void deleteByToIdAndToTypeAndRelationTypeGroupIn(@Param("toId") UUID toId, @Param("toType") String toType, @Param("relationTypeGroups") List<String> relationTypeGroups);
}

7
dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java

@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -66,6 +67,12 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao<RuleNodeEntity, Rul
DaoUtil.toPageable(pageLink)));
}
@Override
public List<RuleNode> findByExternalIds(RuleChainId ruleChainId, List<RuleNodeId> externalIds) {
return DaoUtil.convertDataList(ruleNodeRepository.findRuleNodesByRuleChainIdAndExternalIdIn(ruleChainId.getId(),
externalIds.stream().map(RuleNodeId::getId).collect(Collectors.toList())));
}
@Override
public void deleteByIdIn(List<RuleNodeId> ruleNodeIds) {
ruleNodeRepository.deleteAllById(ruleNodeIds.stream().map(RuleNodeId::getId).collect(Collectors.toList()));

13
dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java

@ -18,8 +18,10 @@ package org.thingsboard.server.dao.sql.rule;
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.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
import java.util.List;
@ -31,14 +33,19 @@ public interface RuleNodeRepository extends JpaRepository<RuleNodeEntity, UUID>
"(select id from RuleChainEntity rc WHERE rc.tenantId = :tenantId) " +
"AND r.type = :ruleType AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ")
List<RuleNodeEntity> findRuleNodesByTenantIdAndType(@Param("tenantId") UUID tenantId,
@Param("ruleType") String ruleType,
@Param("searchText") String searchText);
@Param("ruleType") String ruleType,
@Param("searchText") String searchText);
@Query("SELECT r FROM RuleNodeEntity r WHERE r.type = :ruleType AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ")
Page<RuleNodeEntity> findAllRuleNodesByType(@Param("ruleType") String ruleType,
@Param("searchText") String searchText,
Pageable pageable);
void deleteByIdIn(List<UUID> ids);
List<RuleNodeEntity> findRuleNodesByRuleChainIdAndExternalIdIn(UUID ruleChainId, List<UUID> externalIds);
@Transactional
@Modifying
@Query("DELETE FROM RuleNodeEntity e where e.id in :ids")
void deleteByIdIn(@Param("ids") List<UUID> ids);
}

1
dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java

@ -62,6 +62,7 @@ public class JpaAdminSettingsDao extends JpaAbstractDao<AdminSettingsEntity, Adm
}
@Override
@Transactional
public void removeByTenantId(UUID tenantId) {
adminSettingsRepository.deleteByTenantId(tenantId);
}

3
dao/src/main/java/org/thingsboard/server/dao/sql/usagerecord/ApiUsageStateRepository.java

@ -42,5 +42,6 @@ public interface ApiUsageStateRepository extends JpaRepository<ApiUsageStateEnti
@Transactional
@Modifying
void deleteByEntityIdAndEntityType(UUID entityId, String entityType);
@Query("DELETE FROM ApiUsageStateEntity e WHERE e.entityId = :entityId and e.entityType = :entityType")
void deleteByEntityIdAndEntityType(@Param("entityId") UUID entityId, @Param("entityType") String entityType);
}

7
dao/src/main/java/org/thingsboard/server/dao/sql/user/UserAuthSettingsRepository.java

@ -16,6 +16,9 @@
package org.thingsboard.server.dao.sql.user;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.dao.model.sql.UserAuthSettingsEntity;
@ -28,6 +31,8 @@ public interface UserAuthSettingsRepository extends JpaRepository<UserAuthSettin
UserAuthSettingsEntity findByUserId(UUID userId);
@Transactional
void deleteByUserId(UUID userId);
@Modifying
@Query("DELETE FROM UserAuthSettingsEntity e WHERE e.userId = :userId")
void deleteByUserId(@Param("userId") UUID userId);
}

4
dao/src/main/resources/sql/schema-entities-idx.sql

@ -67,3 +67,7 @@ CREATE INDEX IF NOT EXISTS idx_dashboard_external_id ON dashboard(tenant_id, ext
CREATE INDEX IF NOT EXISTS idx_customer_external_id ON customer(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_widgets_bundle_external_id ON widgets_bundle(tenant_id, external_id);
CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, external_id);
CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type);

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

@ -185,7 +185,8 @@ CREATE TABLE IF NOT EXISTS rule_node (
type varchar(255),
name varchar(255),
debug_mode boolean,
search_text varchar(255)
search_text varchar(255),
external_id uuid
);
CREATE TABLE IF NOT EXISTS rule_node_state (

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

@ -116,7 +116,7 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest {
saveRelation(relationA);
saveRelation(relationB);
Assert.assertNull(relationService.deleteEntityRelationsAsync(SYSTEM_TENANT_ID, childId).get());
relationService.deleteEntityRelations(SYSTEM_TENANT_ID, childId);
Assert.assertFalse(relationService.checkRelation(SYSTEM_TENANT_ID, parentId, childId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get());

Loading…
Cancel
Save