Unit Tests
[sdc.git] / openecomp-be / lib / openecomp-core-lib / openecomp-zusammen-lib / openecomp-zusammen-plugin / src / main / java / org / openecomp / core / zusammen / plugin / collaboration / RevertService.java
1 package org.openecomp.core.zusammen.plugin.collaboration;
2
3 import com.amdocs.zusammen.datatypes.Id;
4 import com.amdocs.zusammen.datatypes.SessionContext;
5 import com.amdocs.zusammen.datatypes.item.ElementContext;
6 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
7 import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
8
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.HashMap;
12 import java.util.Map;
13 import java.util.Optional;
14
15 public class RevertService {
16
17   private ElementPublicStore elementPublicStore;
18   private ElementPrivateStore elementPrivateStore;
19
20   public RevertService(ElementPublicStore elementPublicStore,
21                        ElementPrivateStore elementPrivateStore) {
22     this.elementPublicStore = elementPublicStore;
23     this.elementPrivateStore = elementPrivateStore;
24   }
25
26   public void revert(SessionContext context, Id itemId, Id versionId, Id revisionId) {
27     ElementContext targetContext = new ElementContext(itemId, versionId);
28     ElementContext sourceContext = new ElementContext(itemId, versionId, revisionId);
29     copyElementsFromPublic(context, sourceContext, targetContext);
30   }
31
32   private void copyElementsFromPublic(SessionContext context, ElementContext sourceContext,
33                                       ElementContext targetContext) {
34     Collection<RevertElementAction> revertElementActions =
35         evaluateRevertElementActions(context, sourceContext, targetContext);
36
37     revertElementActions.forEach(revertElementAction -> revertElementAction.run(context));
38   }
39
40   private Collection<RevertElementAction> evaluateRevertElementActions(SessionContext context,
41                                                                        ElementContext sourceContext,
42                                                                        ElementContext targetContext) {
43
44     Map<Id, Id> sourceElements = elementPublicStore.listIds(context, sourceContext);
45     Map<Id, Id> targetPublicElements = elementPublicStore.listIds(context, targetContext);
46     Collection<SynchronizationStateEntity> synchronizationStateEntities =
47         elementPrivateStore.listSynchronizationStates(context, targetContext);
48
49     Map<Id, Id> targetElements =
50         evaluateTargetElements(targetPublicElements, synchronizationStateEntities);
51
52
53     Collection<RevertElementAction> revertElementActions = new ArrayList<>();
54
55     sourceElements.entrySet().forEach(entry -> {
56       Id sourceElementId = entry.getKey();
57       Id sourceElementRevisionId = entry.getValue();
58
59       if (!targetElements.containsKey(sourceElementId)) {
60         revertElementActions
61             .add(new RevertElementAction(sourceContext, sourceElementId, commands[CREATE]));
62       } else if (!targetElements.get(sourceElementId).equals(sourceElementRevisionId)) {
63         revertElementActions
64             .add(new RevertElementAction(sourceContext, sourceElementId, commands[UPDATE]));
65       }
66     });
67
68     targetElements.entrySet().forEach(entry -> {
69       Id targetElementId = entry.getKey();
70       if (!sourceElements.containsKey(targetElementId)) {
71         revertElementActions
72             .add(new RevertElementAction(targetContext, targetElementId, commands[DELETE]));
73       }
74     });
75
76     return revertElementActions;
77   }
78
79   private Map<Id, Id> evaluateTargetElements(Map<Id, Id> targetPublicElements,
80                                              Collection<SynchronizationStateEntity> syncStates) {
81     Map<Id, Id> targetElements = new HashMap<>(targetPublicElements);
82     syncStates.stream()
83         .filter(SynchronizationStateEntity::isDirty)
84         .forEach(syncState -> targetElements.put(syncState.getId(), Id.ZERO));
85     return targetElements;
86   }
87
88   private static class RevertElementAction {
89     private ElementContext elementContext;
90     private Id elementId;
91     private ActionCommand command;
92
93     private RevertElementAction(ElementContext elementContext, Id elementId,
94                                 ActionCommand command) {
95       this.elementContext = elementContext;
96       this.elementId = elementId;
97       this.command = command;
98     }
99
100     public ElementContext getElementContext() {
101       return elementContext;
102     }
103
104     public Id getElementId() {
105       return elementId;
106     }
107
108     public void run(SessionContext context) {
109       command.run(context, elementContext, elementId);
110     }
111   }
112
113   private interface ActionCommand {
114     void run(SessionContext context, ElementContext elementContext, Id elementId);
115   }
116
117   private static int CREATE = 0;
118   private static int UPDATE = 1;
119   private static int DELETE = 2;
120
121   private ActionCommand[] commands = {new ActionCommand() {
122     @Override
123     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
124       //create
125       Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
126       if (!element.isPresent()) {
127         throw getMissingElementException(elementContext, elementId);
128       }
129       elementPrivateStore.create(context, elementContext, element.get());
130     }
131   }, new ActionCommand() {
132     @Override
133     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
134       //update
135       Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
136       if (!element.isPresent()) {
137         throw getMissingElementException(elementContext, elementId);
138       }
139       elementPrivateStore.update(context, elementContext, element.get());
140     }
141   }, new ActionCommand() {
142     @Override
143     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
144       //delete
145       Optional<ElementEntity> element = elementPrivateStore.get(context, elementContext, elementId);
146       if (!element.isPresent()) {
147         return; // deleted by parent when hierarchy was deleted
148       }
149       elementPrivateStore.delete(context, elementContext, element.get());
150     }
151   }};
152
153   private RuntimeException getMissingElementException(ElementContext elementContext,
154                                                       Id elementId) {
155     return new IllegalStateException(
156         String.format("Item Id %s, version Id %s, revision Id %s: Missing element with Id %s",
157             elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
158             elementContext.getRevisionId().getValue(), elementId.getValue())
159     );
160   }
161 }