Improve Relation Service
This commit is contained in:
parent
084907dfc4
commit
9175aba24f
@ -16,6 +16,7 @@
|
|||||||
package org.thingsboard.server.dao.relation;
|
package org.thingsboard.server.dao.relation;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.util.concurrent.AsyncFunction;
|
||||||
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 lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -176,97 +177,64 @@ public class BaseRelationService implements RelationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteEntityRelations(EntityId entity) {
|
public void deleteEntityRelations(EntityId entityId) throws ExecutionException, InterruptedException {
|
||||||
Cache cache = cacheManager.getCache(RELATIONS_CACHE);
|
deleteEntityRelationsAsync(entityId).get();
|
||||||
log.trace("Executing deleteEntityRelations [{}]", entity);
|
|
||||||
validate(entity);
|
|
||||||
List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>();
|
|
||||||
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
|
||||||
inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup));
|
|
||||||
}
|
|
||||||
ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
|
|
||||||
ListenableFuture<List<Boolean>> inboundDeletions = Futures.transform(inboundRelations, relations ->
|
|
||||||
getBooleans(relations, cache, true));
|
|
||||||
|
|
||||||
ListenableFuture<Boolean> inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction());
|
|
||||||
boolean inboundDeleteResult = false;
|
|
||||||
try {
|
|
||||||
inboundDeleteResult = inboundFuture.get();
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
log.error("Error deleting entity inbound relations", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>();
|
|
||||||
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
|
||||||
outboundRelationsList.add(relationDao.findAllByFrom(entity, typeGroup));
|
|
||||||
}
|
|
||||||
ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList);
|
|
||||||
Futures.transform(outboundRelations, relations -> getBooleans(relations, cache, false));
|
|
||||||
|
|
||||||
boolean outboundDeleteResult = relationDao.deleteOutboundRelations(entity);
|
|
||||||
return inboundDeleteResult && outboundDeleteResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Boolean> getBooleans(List<List<EntityRelation>> relations, Cache cache, boolean isRemove) {
|
|
||||||
List<Boolean> results = new ArrayList<>();
|
|
||||||
for (List<EntityRelation> relationList : relations) {
|
|
||||||
relationList.forEach(relation -> checkFromDeleteSync(cache, results, relation, isRemove));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkFromDeleteSync(Cache cache, List<Boolean> results, EntityRelation relation, boolean isRemove) {
|
|
||||||
if (isRemove) {
|
|
||||||
results.add(relationDao.deleteRelation(relation));
|
|
||||||
}
|
|
||||||
cacheEviction(relation, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> deleteEntityRelationsAsync(EntityId entity) {
|
public ListenableFuture<Void> deleteEntityRelationsAsync(EntityId entityId) {
|
||||||
Cache cache = cacheManager.getCache(RELATIONS_CACHE);
|
Cache cache = cacheManager.getCache(RELATIONS_CACHE);
|
||||||
log.trace("Executing deleteEntityRelationsAsync [{}]", entity);
|
log.trace("Executing deleteEntityRelationsAsync [{}]", entityId);
|
||||||
validate(entity);
|
validate(entityId);
|
||||||
List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>();
|
List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>();
|
||||||
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
||||||
inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup));
|
inboundRelationsList.add(relationDao.findAllByTo(entityId, typeGroup));
|
||||||
}
|
}
|
||||||
ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
|
|
||||||
ListenableFuture<List<Boolean>> inboundDeletions = Futures.transformAsync(inboundRelations,
|
|
||||||
relations -> {
|
|
||||||
List<ListenableFuture<Boolean>> results = getListenableFutures(relations, cache, true);
|
|
||||||
return Futures.allAsList(results);
|
|
||||||
});
|
|
||||||
|
|
||||||
ListenableFuture<Boolean> inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction());
|
ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
|
||||||
|
|
||||||
List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>();
|
List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>();
|
||||||
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
|
||||||
outboundRelationsList.add(relationDao.findAllByFrom(entity, typeGroup));
|
outboundRelationsList.add(relationDao.findAllByFrom(entityId, typeGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList);
|
ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList);
|
||||||
Futures.transformAsync(outboundRelations, relations -> {
|
|
||||||
List<ListenableFuture<Boolean>> results = getListenableFutures(relations, cache, false);
|
ListenableFuture<List<Boolean>> inboundDeletions = Futures.transformAsync(inboundRelations,
|
||||||
|
relations -> {
|
||||||
|
List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(relations, cache, true);
|
||||||
return Futures.allAsList(results);
|
return Futures.allAsList(results);
|
||||||
});
|
});
|
||||||
|
|
||||||
ListenableFuture<Boolean> outboundFuture = relationDao.deleteOutboundRelationsAsync(entity);
|
ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations,
|
||||||
return Futures.transform(Futures.allAsList(Arrays.asList(inboundFuture, outboundFuture)), getListToBooleanFunction());
|
relations -> {
|
||||||
|
List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(relations, cache, false);
|
||||||
|
return Futures.allAsList(results);
|
||||||
|
});
|
||||||
|
|
||||||
|
ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions);
|
||||||
|
|
||||||
|
return Futures.transformAsync(deletionsFuture, (deletions) -> {
|
||||||
|
relationDao.deleteOutboundRelationsAsync(entityId);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ListenableFuture<Boolean>> getListenableFutures(List<List<EntityRelation>> relations, Cache cache, boolean isRemove) {
|
private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(List<List<EntityRelation>> relations, Cache cache, boolean deleteFromDb) {
|
||||||
List<ListenableFuture<Boolean>> results = new ArrayList<>();
|
List<ListenableFuture<Boolean>> results = new ArrayList<>();
|
||||||
for (List<EntityRelation> relationList : relations) {
|
for (List<EntityRelation> relationList : relations) {
|
||||||
relationList.forEach(relation -> checkFromDeleteAsync(cache, results, relation, isRemove));
|
relationList.forEach(relation -> results.add(deleteAsync(cache, relation, deleteFromDb)));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFromDeleteAsync(Cache cache, List<ListenableFuture<Boolean>> results, EntityRelation relation, boolean isRemove) {
|
private ListenableFuture<Boolean> deleteAsync(Cache cache, EntityRelation relation, boolean deleteFromDb) {
|
||||||
if (isRemove) {
|
|
||||||
results.add(relationDao.deleteRelationAsync(relation));
|
|
||||||
}
|
|
||||||
cacheEviction(relation, cache);
|
cacheEviction(relation, cache);
|
||||||
|
if (deleteFromDb) {
|
||||||
|
return relationDao.deleteRelationAsync(relation);
|
||||||
|
} else {
|
||||||
|
return Futures.immediateFuture(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cacheEviction(EntityRelation relation, Cache cache) {
|
private void cacheEviction(EntityRelation relation, Cache cache) {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
|
|||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ashvayka on 27.04.17.
|
* Created by ashvayka on 27.04.17.
|
||||||
@ -47,9 +48,9 @@ public interface RelationService {
|
|||||||
|
|
||||||
ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
|
ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
|
||||||
|
|
||||||
boolean deleteEntityRelations(EntityId entity);
|
void deleteEntityRelations(EntityId entity) throws ExecutionException, InterruptedException;
|
||||||
|
|
||||||
ListenableFuture<Boolean> deleteEntityRelationsAsync(EntityId entity);
|
ListenableFuture<Void> deleteEntityRelationsAsync(EntityId entity);
|
||||||
|
|
||||||
List<EntityRelation> findByFrom(EntityId from, RelationTypeGroup typeGroup);
|
List<EntityRelation> findByFrom(EntityId from, RelationTypeGroup typeGroup);
|
||||||
|
|
||||||
|
|||||||
@ -132,39 +132,35 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
|
|||||||
@Override
|
@Override
|
||||||
public boolean deleteRelation(EntityRelation relation) {
|
public boolean deleteRelation(EntityRelation relation) {
|
||||||
RelationCompositeKey key = new RelationCompositeKey(relation);
|
RelationCompositeKey key = new RelationCompositeKey(relation);
|
||||||
boolean relationExistsBeforeDelete = relationRepository.exists(key);
|
return deleteRelationIfExists(key);
|
||||||
relationRepository.delete(key);
|
|
||||||
return relationExistsBeforeDelete;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation) {
|
public ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation) {
|
||||||
RelationCompositeKey key = new RelationCompositeKey(relation);
|
RelationCompositeKey key = new RelationCompositeKey(relation);
|
||||||
return service.submit(
|
return service.submit(
|
||||||
() -> {
|
() -> deleteRelationIfExists(key));
|
||||||
boolean relationExistsBeforeDelete = relationRepository.exists(key);
|
|
||||||
relationRepository.delete(key);
|
|
||||||
return relationExistsBeforeDelete;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
|
public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
|
||||||
RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup);
|
RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup);
|
||||||
boolean relationExistsBeforeDelete = relationRepository.exists(key);
|
return deleteRelationIfExists(key);
|
||||||
relationRepository.delete(key);
|
|
||||||
return relationExistsBeforeDelete;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
|
public ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
|
||||||
RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup);
|
RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup);
|
||||||
return service.submit(
|
return service.submit(
|
||||||
() -> {
|
() -> deleteRelationIfExists(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean deleteRelationIfExists(RelationCompositeKey key) {
|
||||||
boolean relationExistsBeforeDelete = relationRepository.exists(key);
|
boolean relationExistsBeforeDelete = relationRepository.exists(key);
|
||||||
|
if (relationExistsBeforeDelete) {
|
||||||
relationRepository.delete(key);
|
relationRepository.delete(key);
|
||||||
|
}
|
||||||
return relationExistsBeforeDelete;
|
return relationExistsBeforeDelete;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -172,7 +168,9 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
|
|||||||
boolean relationExistsBeforeDelete = relationRepository
|
boolean relationExistsBeforeDelete = relationRepository
|
||||||
.findAllByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name())
|
.findAllByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name())
|
||||||
.size() > 0;
|
.size() > 0;
|
||||||
|
if (relationExistsBeforeDelete) {
|
||||||
relationRepository.deleteByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name());
|
relationRepository.deleteByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name());
|
||||||
|
}
|
||||||
return relationExistsBeforeDelete;
|
return relationExistsBeforeDelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +181,9 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
|
|||||||
boolean relationExistsBeforeDelete = relationRepository
|
boolean relationExistsBeforeDelete = relationRepository
|
||||||
.findAllByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name())
|
.findAllByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name())
|
||||||
.size() > 0;
|
.size() > 0;
|
||||||
|
if (relationExistsBeforeDelete) {
|
||||||
relationRepository.deleteByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name());
|
relationRepository.deleteByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name());
|
||||||
|
}
|
||||||
return relationExistsBeforeDelete;
|
return relationExistsBeforeDelete;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user