[SDC] rebase 1710 code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsontitan / operations / GroupsOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 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.be.model.jsontitan.operations;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
28
29 import org.apache.tinkerpop.shaded.minlog.Log;
30 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
31 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
32 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
34 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
35 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
39 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
40 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
41 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
42 import org.openecomp.sdc.be.model.Component;
43 import org.openecomp.sdc.be.model.GroupDefinition;
44 import org.openecomp.sdc.be.model.GroupInstance;
45 import org.openecomp.sdc.be.model.GroupInstanceProperty;
46 import org.openecomp.sdc.be.model.GroupProperty;
47 import org.openecomp.sdc.be.model.User;
48 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
49 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
50 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
51 import org.openecomp.sdc.be.model.operations.impl.LifecycleOperation;
52 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
53 import org.openecomp.sdc.be.resources.data.GroupData;
54 import org.openecomp.sdc.common.api.Constants;
55 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
56 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 import com.carrotsearch.junitbenchmarks.annotation.LabelType;
61 import com.thinkaurelius.titan.diskstorage.Entry;
62
63 import fj.data.Either;
64 import javassist.expr.NewArray;
65
66 @org.springframework.stereotype.Component("groups-operation")
67 public class GroupsOperation extends BaseOperation {
68
69         private static Logger logger = LoggerFactory.getLogger(GroupsOperation.class.getName());
70
71         public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, User user, ComponentTypeEnum componentType, Map<String, GroupDataDefinition> groups) {
72
73                 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
74                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
75                 StorageOperationStatus status = null;
76
77                 if (result == null) {
78                         getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
79                         if (getComponentVertex.isRight()) {
80                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
81                         }
82                 }
83                 if (result == null) {
84                         status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
85                         if (status != StorageOperationStatus.OK) {
86                                 result = Either.right(status);
87                         }
88                 }
89         /*      if (result == null) {
90                         status = topologyTemplateOperation.associateGroupsPropertiesToComponent(getComponentVertex.left().value(), groupsProperties);
91                         if (status != StorageOperationStatus.OK) {
92                                 result = Either.right(status);
93                         }
94                 }*/
95                 if (result == null) {
96                         result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
97                 }
98                 return result;
99         }
100         
101         public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
102                 // TODO Auto-generated method stub
103                 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
104                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
105                 StorageOperationStatus status = null;
106
107                 if (result == null) {
108                         getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
109                         if (getComponentVertex.isRight()) {
110                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
111                         }
112                 } 
113                 if (result == null) {
114                         status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
115                         
116                         if (status != StorageOperationStatus.OK) {
117                                 result = Either.right(status);
118                         }
119                 }
120                 
121                 if (result == null) {
122                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
123                         result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
124                 }
125                 return result;
126         }
127         
128         public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
129                 // TODO Auto-generated method stub
130                 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
131                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
132                 StorageOperationStatus status = null;
133
134                 if (result == null) {
135                         getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
136                         if (getComponentVertex.isRight()) {
137                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
138                         }
139                 } 
140                 if (result == null) {
141                         List<String> groupName = groups.stream().map(g -> g.getName()).collect(Collectors.toList());
142                         status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupName);
143                                                 
144                         if (status != StorageOperationStatus.OK) {
145                                 result = Either.right(status);
146                         }
147                 }
148                 
149                 if (result == null) {
150                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
151                         result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
152                 }
153                 return result;
154         }
155         
156         public Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
157                 // TODO Auto-generated method stub
158                 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
159                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
160                 StorageOperationStatus status = null;
161
162                 if (result == null) {
163                         getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
164                         if (getComponentVertex.isRight()) {
165                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
166                         }
167                 } 
168                 if (result == null) {
169                         groups.forEach(gr -> {
170                                 String version = gr.getVersion();
171                                 String newVersion = increaseMajorVersion(version);
172                                 gr.setVersion(newVersion);
173                                 String groupUUID = UniqueIdBuilder.generateUUID();
174                                 gr.setGroupUUID(groupUUID);
175                         });
176
177                         status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
178                                                 
179                         if (status != StorageOperationStatus.OK) {
180                                 result = Either.right(status);
181                         }
182                 }
183                 
184                 if (result == null) {
185                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
186                         result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
187                 }
188                 return result;
189         }
190         
191         
192         public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties) {
193                 
194                 Either<List<GroupProperty>,StorageOperationStatus> result = null;
195                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
196                 GraphVertex componentVertex = null;
197                 StorageOperationStatus status = null;
198
199                 if (result == null) {
200                         getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
201                         if (getComponentVertex.isRight()) {
202                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
203                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
204                         }
205                 } 
206                 if (result == null) {
207                         componentVertex = getComponentVertex.left().value();
208                         //update 
209                         List<PropertyDataDefinition> properties = group.getProperties();
210                         newGroupProperties.forEach(np -> {
211                                 Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
212                                 if (currentProp.isPresent()) {  
213                                         currentProp.get().setValue(np.getValue());
214                                 }
215                         });
216                         
217                         StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.NAME);
218                         if ( updateDataRes != StorageOperationStatus.OK ){
219                                 logger.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
220                                 result = Either.right(updateDataRes);
221                         }
222                 }
223                 if (result == null) {
224                         componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
225                         Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(componentVertex);
226                         if (updateRes.isRight()) {
227                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ",  componentId, updateRes.right().value());
228                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
229                         }
230                 }
231                 if (result == null) {
232                         result = Either.left(newGroupProperties);
233                 }
234                 return result;
235         }
236         
237         /**
238          * The version of the group is an integer. In order to support BC, we might get a version in a float format.
239          * 
240          * @param version
241          * @return
242          */
243         private String increaseMajorVersion(String version) {
244
245                 String[] versionParts = version.split(LifecycleOperation.VERSION_DELIMETER_REGEXP);
246                 Integer majorVersion = Integer.parseInt(versionParts[0]);
247
248                 majorVersion++;
249
250                 return String.valueOf(majorVersion);
251
252         }
253
254         public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, ComponentTypeEnum componentType, String instanceId, List<GroupInstance> updatedGroupInstances) {
255
256                 Either<List<GroupInstance>, StorageOperationStatus> result = null;
257                 StorageOperationStatus status = null;
258
259                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
260                 if (getComponentVertex.isRight()) {
261                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
262                 }
263                 if (result == null) {
264                         List<String> pathKeys = new ArrayList<>();
265                         pathKeys.add(instanceId);
266                         status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys,  JsonPresentationFields.NAME);
267                         if (status != StorageOperationStatus.OK) {
268                                 result = Either.right(status);
269                         }
270                 }
271                 if (result == null) {
272                         result = Either.left(updatedGroupInstances);
273                 }
274                 return result;
275         }
276
277         public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
278                 StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
279                 if(status != StorageOperationStatus.OK){
280                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
281                         return Either.right(status);
282                 }
283                 return Either.left(currentGroup);
284         }
285
286         public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
287                 StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.NAME);
288                 if(status != StorageOperationStatus.OK){
289                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
290                 }
291                 return status;
292         }
293
294         public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup) {
295                 StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
296                 if(status != StorageOperationStatus.OK){
297                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
298                         return Either.right(status);
299                 }
300                 return Either.left(currentGroup);
301         }
302         
303         public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
304
305                 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
306                 if (getComponentVertex.isRight()) {
307                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
308                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
309                 }
310
311                 List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
312                 newProperties.forEach(np -> {
313                         Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
314                         if (prop.isPresent()) {
315                                 prop.get().setValue(np.getValue());
316                         }
317                 });
318                 GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
319                 List<String> pathKeys = new ArrayList<>();
320                 pathKeys.add(instanceId);
321                 StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
322                 if (updateDataRes != StorageOperationStatus.OK) {
323                         logger.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
324                         return Either.right(updateDataRes);
325                 }
326                 return Either.left(oldGroupInstance);
327         }
328
329 }