Commit d22209ed7304f07b5de94920128e669705d68ecb

Authored by Dima Landiak
Committed by Andrew Shvayka
1 parent ddb60eae

create relation rule node - corrected current relations deletion if selected, refactoring

@@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.action; @@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.action;
18 import com.google.common.util.concurrent.Futures; 18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
20 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
  21 +import org.springframework.util.CollectionUtils;
21 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
22 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
23 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 24 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
@@ -69,41 +70,31 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR @@ -69,41 +70,31 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
69 70
70 @Override 71 @Override
71 protected ListenableFuture<RelationContainer> doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entity, String relationType) { 72 protected ListenableFuture<RelationContainer> doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entity, String relationType) {
72 - ListenableFuture<Boolean> future = createIfAbsent(ctx, msg, entity, relationType); 73 + ListenableFuture<Boolean> future = createRelationIfAbsent(ctx, msg, entity, relationType);
73 return Futures.transform(future, result -> { 74 return Futures.transform(future, result -> {
74 - RelationContainer container = new RelationContainer();  
75 if (result && config.isChangeOriginatorToRelatedEntity()) { 75 if (result && config.isChangeOriginatorToRelatedEntity()) {
76 TbMsg tbMsg = ctx.transformMsg(msg, msg.getType(), entity.getEntityId(), msg.getMetaData(), msg.getData()); 76 TbMsg tbMsg = ctx.transformMsg(msg, msg.getType(), entity.getEntityId(), msg.getMetaData(), msg.getData());
77 - container.setMsg(tbMsg);  
78 - } else {  
79 - container.setMsg(msg); 77 + return new RelationContainer(tbMsg, result);
80 } 78 }
81 - container.setResult(result);  
82 - return container; 79 + return new RelationContainer(msg, result);
83 }, ctx.getDbCallbackExecutor()); 80 }, ctx.getDbCallbackExecutor());
84 } 81 }
85 82
86 - private ListenableFuture<Boolean> createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { 83 + private ListenableFuture<Boolean> createRelationIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) {
87 SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer); 84 SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer);
88 - ListenableFuture<Boolean> checkRelationFuture = Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON), result -> {  
89 - if (!result) {  
90 - if (config.isRemoveCurrentRelations()) {  
91 - return processDeleteRelations(ctx, processFindRelations(ctx, msg, sdId, relationType));  
92 - }  
93 - return Futures.immediateFuture(false);  
94 - }  
95 - return Futures.immediateFuture(true);  
96 - }, ctx.getDbCallbackExecutor()); 85 + return Futures.transformAsync(deleteCurrentRelationsIfNeeded(ctx, msg, sdId, relationType), v ->
  86 + checkRelationAndCreateIfAbsent(ctx, entityContainer, relationType, sdId),
  87 + ctx.getDbCallbackExecutor());
  88 + }
97 89
98 - return Futures.transformAsync(checkRelationFuture, result -> {  
99 - if (!result) {  
100 - return processCreateRelation(ctx, entityContainer, sdId, relationType);  
101 - }  
102 - return Futures.immediateFuture(true);  
103 - }, ctx.getDbCallbackExecutor()); 90 + private ListenableFuture<Void> deleteCurrentRelationsIfNeeded(TbContext ctx, TbMsg msg, SearchDirectionIds sdId, String relationType) {
  91 + if (config.isRemoveCurrentRelations()) {
  92 + return deleteOriginatorRelations(ctx, findOriginatorRelations(ctx, msg, sdId, relationType));
  93 + }
  94 + return Futures.immediateFuture(null);
104 } 95 }
105 96
106 - private ListenableFuture<List<EntityRelation>> processFindRelations(TbContext ctx, TbMsg msg, SearchDirectionIds sdId, String relationType) { 97 + private ListenableFuture<List<EntityRelation>> findOriginatorRelations(TbContext ctx, TbMsg msg, SearchDirectionIds sdId, String relationType) {
107 if (sdId.isOriginatorDirectionFrom()) { 98 if (sdId.isOriginatorDirectionFrom()) {
108 return ctx.getRelationService().findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), relationType, RelationTypeGroup.COMMON); 99 return ctx.getRelationService().findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), relationType, RelationTypeGroup.COMMON);
109 } else { 100 } else {
@@ -111,19 +102,31 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR @@ -111,19 +102,31 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
111 } 102 }
112 } 103 }
113 104
114 - private ListenableFuture<Boolean> processDeleteRelations(TbContext ctx, ListenableFuture<List<EntityRelation>> listListenableFuture) {  
115 - return Futures.transformAsync(listListenableFuture, entityRelations -> {  
116 - if (!entityRelations.isEmpty()) {  
117 - List<ListenableFuture<Boolean>> list = new ArrayList<>();  
118 - for (EntityRelation relation : entityRelations) { 105 + private ListenableFuture<Void> deleteOriginatorRelations(TbContext ctx, ListenableFuture<List<EntityRelation>> originatorRelationsFuture) {
  106 + return Futures.transformAsync(originatorRelationsFuture, originatorRelations -> {
  107 + List<ListenableFuture<Boolean>> list = new ArrayList<>();
  108 + if (!CollectionUtils.isEmpty(originatorRelations)) {
  109 + for (EntityRelation relation : originatorRelations) {
119 list.add(ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), relation)); 110 list.add(ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), relation));
120 } 111 }
121 - return Futures.transform(Futures.allAsList(list), result -> false, ctx.getDbCallbackExecutor());  
122 } 112 }
123 - return Futures.immediateFuture(false); 113 + return Futures.transform(Futures.allAsList(list), result -> null, ctx.getDbCallbackExecutor());
124 }, ctx.getDbCallbackExecutor()); 114 }, ctx.getDbCallbackExecutor());
125 } 115 }
126 116
  117 + private ListenableFuture<Boolean> checkRelationAndCreateIfAbsent(TbContext ctx, EntityContainer entityContainer, String relationType, SearchDirectionIds sdId) {
  118 + return Futures.transformAsync(checkRelation(ctx, sdId, relationType), relationPresent -> {
  119 + if (relationPresent) {
  120 + return Futures.immediateFuture(true);
  121 + }
  122 + return processCreateRelation(ctx, entityContainer, sdId, relationType);
  123 + }, ctx.getDbCallbackExecutor());
  124 + }
  125 +
  126 + private ListenableFuture<Boolean> checkRelation(TbContext ctx, SearchDirectionIds sdId, String relationType) {
  127 + return ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON);
  128 + }
  129 +
127 private ListenableFuture<Boolean> processCreateRelation(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { 130 private ListenableFuture<Boolean> processCreateRelation(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) {
128 switch (entityContainer.getEntityType()) { 131 switch (entityContainer.getEntityType()) {
129 case ASSET: 132 case ASSET: