Added oparent to sdc main
[sdc.git] / openecomp-be / lib / openecomp-sdc-vendor-software-product-lib / openecomp-sdc-vendor-software-product-core / src / main / java / org / openecomp / sdc / vendorsoftwareproduct / dao / impl / VspMergeDaoImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.vendorsoftwareproduct.dao.impl;
22
23 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
24 import com.amdocs.zusammen.datatypes.Id;
25 import com.amdocs.zusammen.datatypes.SessionContext;
26 import com.amdocs.zusammen.datatypes.item.Action;
27 import com.amdocs.zusammen.datatypes.item.ElementContext;
28 import com.amdocs.zusammen.datatypes.item.Resolution;
29 import com.datastax.driver.core.ResultSet;
30 import com.datastax.driver.core.Row;
31 import com.datastax.driver.extras.codecs.enums.EnumNameCodec;
32 import com.datastax.driver.mapping.MappingManager;
33 import com.datastax.driver.mapping.annotations.Accessor;
34 import com.datastax.driver.mapping.annotations.Query;
35 import org.openecomp.core.nosqldb.factory.NoSqlDbFactory;
36 import org.openecomp.core.zusammen.api.ZusammenAdaptor;
37 import org.openecomp.sdc.common.session.SessionContextProviderFactory;
38 import org.openecomp.sdc.datatypes.model.ElementType;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.VspMergeDao;
40 import org.openecomp.sdc.versioning.dao.types.Version;
41
42 import java.util.List;
43 import java.util.stream.Collectors;
44
45 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildElement;
46 import static org.openecomp.core.zusammen.api.ZusammenUtil.createSessionContext;
47
48 public class VspMergeDaoImpl implements VspMergeDao {
49   private static final String VSP_MODEL_NOT_EXIST =
50       "Vsp model does not exist for Vsp %s, version %s.";
51
52   private static final VspMergeHintAccessor accessor;
53
54   static {
55       MappingManager mappingManager = NoSqlDbFactory.getInstance().createInterface().getMappingManager();
56       mappingManager.getSession().getCluster().getConfiguration().getCodecRegistry()
57                     .register(new EnumNameCodec<>(Resolution.class));
58       accessor = mappingManager.createAccessor(VspMergeHintAccessor.class);
59   }
60
61   private ZusammenAdaptor zusammenAdaptor;
62
63   public VspMergeDaoImpl(ZusammenAdaptor zusammenAdaptor) {
64     this.zusammenAdaptor = zusammenAdaptor;
65   }
66
67   @Override
68   public boolean isConflicted(String vspId, Version version) {
69     SessionContext context = createSessionContext();
70     ElementContext elementContext = new ElementContext(new Id(vspId), new Id(version.getId()));
71
72     return listVspModels(context, elementContext).size() > 1;
73   }
74
75   @Override
76   public void updateHint(String vspId, Version version) {
77     SessionContext context = createSessionContext();
78     ElementContext elementContext = new ElementContext(new Id(vspId), new Id(version.getId()));
79
80     String vspModelId = zusammenAdaptor
81         .getElementInfoByName(context, elementContext, null, ElementType.VspModel.name())
82         .orElseThrow(() -> new IllegalStateException(
83             String.format(VSP_MODEL_NOT_EXIST, vspId, version.getId())))
84         .getId().getValue();
85
86     updateVspModelId(vspId, version, vspModelId);
87   }
88
89   @Override
90   public void deleteHint(String vspId, Version version) {
91     accessor.delete(getUser(),vspId,version.getId());
92   }
93
94   @Override
95   public void updateConflictResolution(String vspId, Version version,
96                                        Resolution resolution) {
97     accessor.updateModelResolution(resolution, getUser(), vspId, version.getId());
98   }
99
100   @Override
101   public void applyConflictResolution(String vspId, Version version) {
102     //called only when no conflicts
103
104     SessionContext context = createSessionContext();
105     ElementContext elementContext = new ElementContext(new Id(vspId), new Id(version.getId()));
106
107     List<ElementInfo> vspModels = listVspModels(context, elementContext);
108     if (vspModels.size() == 1) {
109       updateVspModelId(vspId, version, vspModels.iterator().next().getId().getValue());
110       return;
111     }
112
113     if (vspModels.size() != 2) {
114       return;
115     }
116
117     String user = getUser();
118     Row row = accessor.get(user, vspId, version.getId()).one();
119     if (row == null) {
120       throw new IllegalStateException(
121           "Vsp model id must exists if its conflict is being resolved");
122     }
123     String resolutionValue = row.getString("model_resolution");
124     if (resolutionValue == null) {
125       return; // model conflict is not resolved yet
126     }
127
128     Resolution resolution = Resolution.valueOf(resolutionValue);
129     String localModelId = row.getString("model_id");
130
131     String chosenModelId =
132         keepOnlyChosenVspModel(context, elementContext, vspModels, resolution, localModelId);
133
134     accessor.update(chosenModelId, null, user, vspId, version.getId());
135   }
136
137   private String keepOnlyChosenVspModel(SessionContext context, ElementContext elementContext,
138                                         List<ElementInfo> vspModels, Resolution resolution,
139                                         String localModelId) {
140     String newLocalModelId = null;
141     for (ElementInfo vspModel : vspModels) {
142       if (isRedundantModel(vspModel.getId().getValue(), localModelId, resolution)) {
143         zusammenAdaptor
144             .saveElement(context, elementContext, buildElement(vspModel.getId(), Action.DELETE),
145                 "Delete Redundant Vsp Model");
146       } else {
147         newLocalModelId = vspModel.getId().getValue();
148       }
149     }
150     return newLocalModelId;
151   }
152
153   private boolean isRedundantModel(String modelId, String localModelId, Resolution resolution) {
154     return resolution == Resolution.THEIRS && modelId.equals(localModelId) ||
155         resolution == Resolution.YOURS && !modelId.equals(localModelId);
156   }
157
158   private List<ElementInfo> listVspModels(SessionContext context, ElementContext elementContext) {
159     return zusammenAdaptor.listElements(context, elementContext, null).stream()
160         .filter(elementInfo -> ElementType.VspModel.name().equals(elementInfo.getInfo().getName()))
161         .collect(Collectors.toList());
162   }
163
164   private void updateVspModelId(String vspId, Version version, String vspModelId) {
165     accessor.update(vspModelId, null, getUser(), vspId, version.getId());
166   }
167
168   private String getUser() {
169     return SessionContextProviderFactory.getInstance().createInterface()
170         .get().getUser().getUserId();
171   }
172
173   @Accessor
174   interface VspMergeHintAccessor {
175
176     @Query("SELECT model_id, model_resolution FROM vsp_merge_hint " +
177         "WHERE space=? AND item_id=? AND version_id=?")
178     ResultSet get(String space, String itemId, String versionId);
179
180     @Query("UPDATE vsp_merge_hint SET model_id=?, model_resolution=? " +
181         "WHERE space=? AND item_id=? AND version_id=?")
182     void update(String vspModelId, Resolution modelResolution, String space,
183                 String itemId, String versionId);
184
185     @Query(
186         "UPDATE vsp_merge_hint SET model_resolution=? WHERE space=? AND item_id=? AND version_id=?")
187     void updateModelResolution(Resolution modelResolution, String space, String itemId,
188                                String versionId);
189
190     @Query("DELETE from vsp_merge_hint WHERE space=? AND item_id=? AND version_id=?")
191     void delete(String space, String itemId, String versionId);
192   }
193 }