Add collaboration feature
[sdc.git] / openecomp-be / lib / openecomp-conflict-lib / openecomp-conflict-core / src / main / java / org / openecomp / conflicts / impl / VspMergeHandler.java
1 package org.openecomp.conflicts.impl;
2
3 import org.openecomp.conflicts.ItemMergeHandler;
4 import org.openecomp.conflicts.dao.ConflictsDao;
5 import org.openecomp.conflicts.types.Conflict;
6 import org.openecomp.conflicts.types.ConflictInfo;
7 import org.openecomp.conflicts.types.ConflictResolution;
8 import org.openecomp.conflicts.types.ItemVersionConflict;
9 import org.openecomp.conflicts.types.Resolution;
10 import org.openecomp.sdc.common.errors.CoreException;
11 import org.openecomp.sdc.common.errors.ErrorCategory;
12 import org.openecomp.sdc.common.errors.ErrorCode;
13 import org.openecomp.sdc.datatypes.model.ElementType;
14 import org.openecomp.sdc.vendorsoftwareproduct.dao.VspMergeDao;
15 import org.openecomp.sdc.versioning.dao.types.Version;
16
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Optional;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26 import java.util.stream.Stream;
27
28 import static org.openecomp.sdc.datatypes.model.ElementType.NetworkPackage;
29 import static org.openecomp.sdc.datatypes.model.ElementType.OrchestrationTemplate;
30 import static org.openecomp.sdc.datatypes.model.ElementType.OrchestrationTemplateCandidate;
31 import static org.openecomp.sdc.datatypes.model.ElementType.OrchestrationTemplateCandidateContent;
32 import static org.openecomp.sdc.datatypes.model.ElementType.OrchestrationTemplateValidationData;
33 import static org.openecomp.sdc.datatypes.model.ElementType.VspModel;
34
35 public class VspMergeHandler implements ItemMergeHandler {
36
37   private static final String VSP_MODEL_CONFLICT_ID = "vspModelConflictId";
38   private static final String ELEMENT_CONFLICT_NOT_EXIST_ERR_ID = "ELEMENT_CONFLICT_NOT_EXIST";
39   private static final String ELEMENT_CONFLICT_NOT_EXISTS_MSG =
40       "Item Id %s, version Id %s, element conflict with Id %s does not exists.";
41   private static final Set<ElementType> FILTERED_OUT_TYPES = Stream
42       .of(OrchestrationTemplateCandidateContent, OrchestrationTemplateValidationData)
43       .collect(Collectors.toSet());
44   private static final Map<ElementType, Set<ElementType>> ELEMENT_TYPE_TO_CONFLICT_DEPENDANT_TYPES =
45       new HashMap<>();
46
47   static {
48     ELEMENT_TYPE_TO_CONFLICT_DEPENDANT_TYPES.put(OrchestrationTemplateCandidate,
49         Collections.singleton(OrchestrationTemplateCandidateContent));
50     ELEMENT_TYPE_TO_CONFLICT_DEPENDANT_TYPES.put(OrchestrationTemplate,
51         Collections.singleton(OrchestrationTemplateValidationData));
52   }
53
54   private ConflictsDao conflictsDao;
55   private VspMergeDao vspMergeDao;
56
57   public VspMergeHandler(ConflictsDao conflictsDao, VspMergeDao vspMergeDao) {
58     this.conflictsDao = conflictsDao;
59     this.vspMergeDao = vspMergeDao;
60   }
61
62   @Override
63   public boolean isConflicted(String itemId, Version version) {
64     return vspMergeDao.isVspModelConflicted(itemId, version);
65   }
66
67   @Override
68   public void finalizeMerge(String itemId, Version version) {
69     if (!conflictsDao.isConflicted(itemId, version)) {
70       vspMergeDao.applyVspModelConflictResolution(itemId, version);
71     }
72   }
73
74   @Override
75   public void postListConflicts(String itemId, Version version, ItemVersionConflict conflicts) {
76     List<ConflictInfo> elementConflicts = new ArrayList<>();
77
78     boolean vspModelConflicted = false;
79     for (ConflictInfo elementConflict : conflicts.getElementConflicts()) {
80       if (elementConflict.getType() == VspModel) {
81         elementConflicts.add(
82             new ConflictInfo(elementConflict.getId(), NetworkPackage, NetworkPackage.name()));
83         vspModelConflicted = true;
84         continue;
85       }
86       if (!FILTERED_OUT_TYPES.contains(elementConflict.getType())) {
87         elementConflicts.add(elementConflict);
88       }
89     }
90
91     if (!vspModelConflicted && vspMergeDao.isVspModelConflicted(itemId, version)) {
92       elementConflicts
93           .add(new ConflictInfo(VSP_MODEL_CONFLICT_ID, NetworkPackage, NetworkPackage.name()));
94     }
95
96     conflicts.setElementConflicts(elementConflicts);
97   }
98
99   @Override
100   public Optional<Conflict> getConflict(String itemId, Version version, String conflictId) {
101     return VSP_MODEL_CONFLICT_ID.equals(conflictId)
102         ? Optional.of(buildVspModelConflict(conflictId))
103         : Optional.empty();
104   }
105
106   @Override
107   public void postGetConflict(String itemId, Version version, Conflict conflict) {
108     if (conflict.getType() == VspModel) {
109       Conflict vspModelConflict = buildVspModelConflict(null);
110       conflict.setType(vspModelConflict.getType());
111       conflict.setName(vspModelConflict.getName());
112       conflict.setYours(vspModelConflict.getYours());
113       conflict.setTheirs(vspModelConflict.getTheirs());
114     }
115   }
116
117   @Override
118   public void preResolveConflict(String itemId, Version version, String conflictId,
119                                  ConflictResolution resolution) {
120     if (VSP_MODEL_CONFLICT_ID.equals(conflictId)) {
121       return;
122     }
123     resolveDependantConflicts(itemId, version, conflictId, resolution);
124   }
125
126   @Override
127   public boolean resolveConflict(String itemId, Version version, String conflictId,
128                                  ConflictResolution resolution) {
129     if (VSP_MODEL_CONFLICT_ID.equals(conflictId)) {
130       vspMergeDao.updateVspModelConflictResolution(itemId, version,
131           com.amdocs.zusammen.datatypes.item.Resolution.valueOf(resolution.getResolution().name()));
132       return true;
133     }
134     Conflict conflict = conflictsDao.getConflict(itemId, version, conflictId);
135     if (conflict == null) {
136       throw getConflictNotExistException(itemId, version, conflictId);
137     }
138     if (conflict.getType() == VspModel) {
139       vspMergeDao.updateVspModelConflictResolution(itemId, version,
140           com.amdocs.zusammen.datatypes.item.Resolution.valueOf(resolution.getResolution().name()));
141
142       conflictsDao.resolveConflict(itemId, version, conflictId, new ConflictResolution(
143           conflict.getTheirs() == null ? Resolution.YOURS : Resolution.THEIRS));
144       return true;
145     }
146     return false;
147   }
148
149   private void resolveDependantConflicts(String itemId, Version version, String conflictId,
150                                          ConflictResolution resolution) {
151     ItemVersionConflict conflicts = conflictsDao.getConflict(itemId, version);
152
153     Set<ElementType> conflictDependantTypes =
154         ELEMENT_TYPE_TO_CONFLICT_DEPENDANT_TYPES
155             .get(findConflictById(conflicts, conflictId).getType());
156
157     if (conflictDependantTypes == null) {
158       return;
159     }
160
161     findConflictsByTypes(conflicts, conflictDependantTypes)
162         .forEach(dependantConflict ->
163             conflictsDao.resolveConflict(itemId, version, dependantConflict.getId(), resolution));
164   }
165
166   private ConflictInfo findConflictById(ItemVersionConflict versionConflicts,
167                                         String conflictId) {
168     return versionConflicts.getElementConflicts().stream()
169         .filter(elementConflict -> conflictId.equals(elementConflict.getId()))
170         .findFirst()
171         .orElseThrow(() -> new IllegalStateException(
172             String.format("Conflict Id %s does not exist on conflicts list", conflictId)));
173   }
174
175   private Collection<ConflictInfo> findConflictsByTypes(ItemVersionConflict versionConflicts,
176                                                         Set<ElementType> elementTypes) {
177     return versionConflicts.getElementConflicts().stream()
178         .filter(elementConflict -> elementTypes.contains(elementConflict.getType()))
179         .collect(Collectors.toList());
180   }
181
182   private Conflict buildVspModelConflict(String conflictId) {
183     Conflict conflict = new Conflict(conflictId, NetworkPackage, NetworkPackage.name());
184
185     Map<String, String> yours = new HashMap<>();
186     yours.put("File", "Local (Me)");
187     conflict.setYours(yours);
188
189     Map<String, String> theirs = new HashMap<>();
190     theirs.put("File", "Last Committed");
191     conflict.setTheirs(theirs);
192     return conflict;
193   }
194
195   private CoreException getConflictNotExistException(String itemId, Version version,
196                                                      String conflictId) {
197     return new CoreException(new ErrorCode.ErrorCodeBuilder()
198         .withCategory(ErrorCategory.APPLICATION)
199         .withId(ELEMENT_CONFLICT_NOT_EXIST_ERR_ID)
200         .withMessage(
201             String.format(ELEMENT_CONFLICT_NOT_EXISTS_MSG, itemId, version.getId(), conflictId))
202         .build());
203   }
204 }