1 package org.openecomp.core.zusammen.plugin.collaboration;
 
   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;
 
   9 import java.util.ArrayList;
 
  10 import java.util.Collection;
 
  11 import java.util.HashMap;
 
  13 import java.util.Optional;
 
  15 public class RevertService {
 
  17   private ElementPublicStore elementPublicStore;
 
  18   private ElementPrivateStore elementPrivateStore;
 
  20   public RevertService(ElementPublicStore elementPublicStore,
 
  21                        ElementPrivateStore elementPrivateStore) {
 
  22     this.elementPublicStore = elementPublicStore;
 
  23     this.elementPrivateStore = elementPrivateStore;
 
  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);
 
  32   private void copyElementsFromPublic(SessionContext context, ElementContext sourceContext,
 
  33                                       ElementContext targetContext) {
 
  34     Collection<RevertElementAction> revertElementActions =
 
  35         evaluateRevertElementActions(context, sourceContext, targetContext);
 
  37     revertElementActions.forEach(revertElementAction -> revertElementAction.run(context));
 
  40   private Collection<RevertElementAction> evaluateRevertElementActions(SessionContext context,
 
  41                                                                        ElementContext sourceContext,
 
  42                                                                        ElementContext targetContext) {
 
  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);
 
  49     Map<Id, Id> targetElements =
 
  50         evaluateTargetElements(targetPublicElements, synchronizationStateEntities);
 
  53     Collection<RevertElementAction> revertElementActions = new ArrayList<>();
 
  55     sourceElements.entrySet().forEach(entry -> {
 
  56       Id sourceElementId = entry.getKey();
 
  57       Id sourceElementRevisionId = entry.getValue();
 
  59       if (!targetElements.containsKey(sourceElementId)) {
 
  61             .add(new RevertElementAction(sourceContext, sourceElementId, commands[CREATE]));
 
  62       } else if (!targetElements.get(sourceElementId).equals(sourceElementRevisionId)) {
 
  64             .add(new RevertElementAction(sourceContext, sourceElementId, commands[UPDATE]));
 
  68     targetElements.entrySet().forEach(entry -> {
 
  69       Id targetElementId = entry.getKey();
 
  70       if (!sourceElements.containsKey(targetElementId)) {
 
  72             .add(new RevertElementAction(targetContext, targetElementId, commands[DELETE]));
 
  76     return revertElementActions;
 
  79   private Map<Id, Id> evaluateTargetElements(Map<Id, Id> targetPublicElements,
 
  80                                              Collection<SynchronizationStateEntity> syncStates) {
 
  81     Map<Id, Id> targetElements = new HashMap<>(targetPublicElements);
 
  83         .filter(SynchronizationStateEntity::isDirty)
 
  84         .forEach(syncState -> targetElements.put(syncState.getId(), Id.ZERO));
 
  85     return targetElements;
 
  88   private static class RevertElementAction {
 
  89     private ElementContext elementContext;
 
  91     private ActionCommand command;
 
  93     private RevertElementAction(ElementContext elementContext, Id elementId,
 
  94                                 ActionCommand command) {
 
  95       this.elementContext = elementContext;
 
  96       this.elementId = elementId;
 
  97       this.command = command;
 
 100     public ElementContext getElementContext() {
 
 101       return elementContext;
 
 104     public Id getElementId() {
 
 108     public void run(SessionContext context) {
 
 109       command.run(context, elementContext, elementId);
 
 113   private interface ActionCommand {
 
 114     void run(SessionContext context, ElementContext elementContext, Id elementId);
 
 117   private static int CREATE = 0;
 
 118   private static int UPDATE = 1;
 
 119   private static int DELETE = 2;
 
 121   private ActionCommand[] commands = {new ActionCommand() {
 
 123     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
 
 125       Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
 
 126       if (!element.isPresent()) {
 
 127         throw getMissingElementException(elementContext, elementId);
 
 129       elementPrivateStore.create(context, elementContext, element.get());
 
 131   }, new ActionCommand() {
 
 133     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
 
 135       Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
 
 136       if (!element.isPresent()) {
 
 137         throw getMissingElementException(elementContext, elementId);
 
 139       elementPrivateStore.update(context, elementContext, element.get());
 
 141   }, new ActionCommand() {
 
 143     public void run(SessionContext context, ElementContext elementContext, Id elementId) {
 
 145       Optional<ElementEntity> element = elementPrivateStore.get(context, elementContext, elementId);
 
 146       if (!element.isPresent()) {
 
 147         return; // deleted by parent when hierarchy was deleted
 
 149       elementPrivateStore.delete(context, elementContext, element.get());
 
 153   private RuntimeException getMissingElementException(ElementContext elementContext,
 
 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())