re base code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / GroupOperation.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.operations.impl;
22
23 import fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.config.BeEcompErrorManager;
26 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
27 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
28 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
29 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
30 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
31 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
32 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
33 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
34 import org.openecomp.sdc.be.dao.utils.MapUtil;
35 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
38 import org.openecomp.sdc.be.model.*;
39 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
40 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
41 import org.openecomp.sdc.be.model.operations.StorageException;
42 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
43 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
44 import org.openecomp.sdc.be.resources.data.*;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46 import org.springframework.stereotype.Component;
47
48 import java.util.*;
49 import java.util.function.Function;
50 import java.util.stream.Collectors;
51
52 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
53 import static org.springframework.util.CollectionUtils.isEmpty;
54
55
56 @Component
57 public class GroupOperation extends AbstractOperation implements IGroupOperation {
58
59
60     private static final Logger log = Logger.getLogger(GroupOperation.class.getName());
61         private final TitanDao titanDao;
62         private final TopologyTemplateOperation topologyTemplateOperation;
63     private final PropertyOperation propertyOperation;
64     private final GroupTypeOperation groupTypeOperation;
65     private final ApplicationDataTypeCache dataTypeCache;
66
67     public GroupOperation(TitanDao titanDao, TopologyTemplateOperation topologyTemplateOperation, PropertyOperation propertyOperation, GroupTypeOperation groupTypeOperation, ApplicationDataTypeCache dataTypeCache) {
68         this.titanDao = titanDao;
69         this.topologyTemplateOperation = topologyTemplateOperation;
70         this.propertyOperation = propertyOperation;
71         this.groupTypeOperation = groupTypeOperation;
72         this.dataTypeCache = dataTypeCache;
73     }
74
75     private GroupDefinition convertGroupDataToGroupDefinition(GroupData groupData) {
76                 return new GroupDefinition(groupData.getGroupDataDefinition());
77
78         }
79
80     /**
81      * get members of group
82      *
83      * @param groupUniqueId
84      * @return
85      */
86     private Either<Map<String, String>, TitanOperationStatus> getGroupMembers(String groupUniqueId) {
87
88         Either<Map<String, String>, TitanOperationStatus> result = null;
89
90         Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_MEMBER,
91                 NodeTypeEnum.ResourceInstance, ComponentInstanceData.class);
92
93         if (childrenNodes.isRight()) {
94             TitanOperationStatus status = childrenNodes.right().value();
95             if (status == TitanOperationStatus.NOT_FOUND) {
96                 status = TitanOperationStatus.OK;
97             }
98             result = Either.right(status);
99
100         } else {
101
102             Map<String, String> compInstaMap = new HashMap<>();
103             List<ImmutablePair<ComponentInstanceData, GraphEdge>> list = childrenNodes.left().value();
104             if (list != null) {
105                 for (ImmutablePair<ComponentInstanceData, GraphEdge> pair : list) {
106                     ComponentInstanceData componentInstanceData = pair.getKey();
107
108                     String compInstUniqueId = componentInstanceData.getComponentInstDataDefinition().getUniqueId();
109                     String compInstName = componentInstanceData.getName();
110                     compInstaMap.put(compInstName, compInstUniqueId);
111                 }
112             }
113
114             result = Either.left(compInstaMap);
115         }
116
117         return result;
118     }
119
120     private Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeOfGroup(String groupUniqueId) {
121
122         Either<ImmutablePair<GroupTypeData, GraphEdge>, StorageOperationStatus> groupTypeRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.TYPE_OF, NodeTypeEnum.GroupType,
123                 GroupTypeData.class)
124                 .right()
125                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
126
127         if (groupTypeRes.isRight()) {
128             StorageOperationStatus status = groupTypeRes.right().value();
129             log.debug("Cannot find group type associated with capability {}. Status is {}", groupUniqueId, status);
130
131             BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Group type", NodeTypeEnum.GroupType.getName(), groupUniqueId, String.valueOf(status));
132             return Either.right(groupTypeRes.right().value());
133         }
134
135         GroupTypeData groupTypeData = groupTypeRes.left().value().getKey();
136
137         return groupTypeOperation.getGroupTypeByUid(groupTypeData.getGroupTypeDataDefinition().getUniqueId());
138
139     }
140
141     /**
142      * get all properties of the group.
143      *
144      * the propert definition is taken from the group type.
145      *
146      * @param groupUid
147      * @return
148      */
149     private Either<List<GroupProperty>, StorageOperationStatus> getGroupProperties(String groupUid) {
150
151         List<GroupProperty> groupPropertiesList = new ArrayList<>();
152
153         Either<GroupTypeDefinition, StorageOperationStatus> groupTypeOfGroupRes = getGroupTypeOfGroup(groupUid);
154
155         if (groupTypeOfGroupRes.isRight()) {
156             StorageOperationStatus status = groupTypeOfGroupRes.right().value();
157             return Either.right(status);
158         }
159
160         GroupTypeDefinition groupTypeDefinition = groupTypeOfGroupRes.left().value();
161
162         // Get the properties on the group type of this group
163         List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
164
165         if (isEmpty(groupTypeProperties)) {
166             return Either.right(StorageOperationStatus.OK);
167         }
168
169         Map<String, PropertyDefinition> uidToPropDefMap = groupTypeProperties.stream().collect(Collectors.toMap(PropertyDefinition::getUniqueId, Function.identity()));
170
171         // Find all properties values on the group
172         Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, StorageOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUid, GraphEdgeLabels.PROPERTY_VALUE,
173                 NodeTypeEnum.PropertyValue, PropertyValueData.class)
174                 .right()
175                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
176
177         if (propertyImplNodes.isRight()) {
178             StorageOperationStatus status = propertyImplNodes.right().value();
179             if (status == StorageOperationStatus.NOT_FOUND) {
180                 groupPropertiesList = groupTypeProperties.stream().map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList());
181                 return Either.left(groupPropertiesList);
182             } else {
183                 return Either.right(status);
184             }
185         }
186
187         List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value();
188         if (isEmpty(list)) {
189             return Either.right(StorageOperationStatus.OK);
190         }
191
192         List<String> processedProps = new ArrayList<>();
193
194         for (ImmutablePair<PropertyValueData, GraphEdge> propertyValue : list) {
195
196             PropertyValueData propertyValueData = propertyValue.getLeft();
197             String propertyValueUid = propertyValueData.getUniqueId();
198             String value = propertyValueData.getValue();
199
200             Either<ImmutablePair<PropertyData, GraphEdge>, StorageOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL,
201                     NodeTypeEnum.Property, PropertyData.class)
202                     .right()
203                     .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
204             if (propertyDefRes.isRight()) {
205                 StorageOperationStatus status = propertyDefRes.right().value();
206                 if (status == StorageOperationStatus.NOT_FOUND) {
207                     status = StorageOperationStatus.INVALID_ID;
208                 }
209                 return Either.right(status);
210             }
211
212             ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value();
213
214             PropertyData propertyData = propertyDefPair.left;
215             String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId();
216
217             PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId);
218             GroupProperty groupProperty = new GroupProperty(propertyDefinition, value, propertyValueUid);
219
220             processedProps.add(propertyUniqueId);
221
222             groupPropertiesList.add(groupProperty);
223
224         }
225
226         // Find all properties which does not have property value on the group.
227         List<GroupProperty> leftProps = groupTypeProperties.stream()
228                 // filter out the group type properties which already processed
229                 .filter(p -> !processedProps.contains(p.getUniqueId()))
230                 .map(p -> new GroupProperty(p, p.getDefaultValue(), null))
231                 .collect(Collectors.toList());
232         if (leftProps != null) {
233             groupPropertiesList.addAll(leftProps);
234         }
235
236         return Either.left(groupPropertiesList);
237     }
238
239     @Override
240     public Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String artifactId) {
241
242         List<GraphRelation> relations = new ArrayList<>();
243         Either<List<GraphRelation>, StorageOperationStatus> result = Either.left(relations);
244
245         Either<List<GroupDefinition>, StorageOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
246         if (allGroupsFromGraph.isRight()) {
247             StorageOperationStatus status = allGroupsFromGraph.right().value();
248             return Either.right(status);
249         }
250
251         List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
252         if (isEmpty(allGroups)) {
253             return Either.right(StorageOperationStatus.OK);
254         }
255
256         // Find all groups which contains this artifact id
257         List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(artifactId)).collect(Collectors.toList());
258
259         if (isNotEmpty(associatedGroups)) {
260             log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(GroupDataDefinition::getName).collect(Collectors.toList()), artifactId);
261
262             UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
263             for (GroupDefinition groupDefinition : associatedGroups) {
264                 UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
265                 Either<GraphRelation, StorageOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF)
266                         .right()
267                         .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
268                 if (deleteRelation.isRight()) {
269                     StorageOperationStatus status = deleteRelation.right().value();
270                     if (status == StorageOperationStatus.NOT_FOUND) {
271                         status = StorageOperationStatus.INVALID_ID;
272                     }
273                     return Either.right(status);
274                 }
275
276                 relations.add(deleteRelation.left().value());
277             }
278
279             return result;
280
281         } else {
282             log.debug("No group under component id {} is associated to artifact {}", componentId, artifactId);
283             return Either.right(StorageOperationStatus.OK);
284         }
285
286     }
287
288     public Either<GroupDefinition, StorageOperationStatus> getGroupFromGraph(String uniqueId, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
289
290         Either<GroupDefinition, StorageOperationStatus> result = null;
291
292         Either<GroupData, StorageOperationStatus> groupRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), uniqueId, GroupData.class)
293                 .right()
294                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
295         if (groupRes.isRight()) {
296             StorageOperationStatus status = groupRes.right().value();
297             log.debug("Failed to retrieve group {}  from graph. Status is {}", uniqueId, status);
298             BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, String.valueOf(status));
299             result = Either.right(status);
300             return result;
301         }
302
303         GroupData groupData = groupRes.left().value();
304
305         GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData);
306
307         Either<GroupTypeDefinition, StorageOperationStatus> groupTypeOfGroup = getGroupTypeOfGroup(uniqueId);
308
309         if (groupTypeOfGroup.isRight()) {
310             StorageOperationStatus status = groupTypeOfGroup.right().value();
311             log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status);
312
313             result = Either.right(status);
314             return result;
315         }
316
317         GroupTypeDefinition groupTypeDefinition = groupTypeOfGroup.left().value();
318
319         groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
320
321         if (!skipMembers) {
322             Either<Map<String, String>, StorageOperationStatus> membersRes = getGroupMembers(uniqueId)
323                     .right()
324                     .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
325             if (membersRes.isRight()) {
326                 StorageOperationStatus status = membersRes.right().value();
327                 if (status != StorageOperationStatus.OK) {
328                     result = Either.right(status);
329                     return result;
330                 }
331             } else {
332                 Map<String, String> members = membersRes.left().value();
333                 groupDefinition.setMembers(members);
334             }
335         }
336
337         if (!skipProperties) {
338             Either<List<GroupProperty>, StorageOperationStatus> propertiesRes = getGroupProperties(uniqueId);
339             if (propertiesRes.isRight()) {
340                 StorageOperationStatus status = propertiesRes.right().value();
341                 if (status != StorageOperationStatus.OK) {
342                     result = Either.right(status);
343                     return result;
344                 }
345             } else {
346                 List<GroupProperty> properties = propertiesRes.left().value();
347                 groupDefinition.convertFromGroupProperties(properties);
348             }
349         }
350
351         if (!skipArtifacts) {
352             Either<List<ImmutablePair<String, String>>, StorageOperationStatus> artifactsRes = getGroupArtifactsPairs(uniqueId)
353                     .right()
354                     .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
355             if (artifactsRes.isRight()) {
356                 StorageOperationStatus status = artifactsRes.right().value();
357                 if (status != StorageOperationStatus.OK) {
358                     result = Either.right(status);
359                     return result;
360                 }
361             } else {
362                 List<String> artifactsUid = new ArrayList<>();
363                 List<String> artifactsUUID = new ArrayList<>();
364
365                 List<ImmutablePair<String, String>> list = artifactsRes.left().value();
366                 if (list != null) {
367                     for (ImmutablePair<String, String> pair : list) {
368                         String uid = pair.left;
369                         String UUID = pair.right;
370                         artifactsUid.add(uid);
371                         artifactsUUID.add(UUID);
372                     }
373                     groupDefinition.setArtifacts(artifactsUid);
374                     groupDefinition.setArtifactsUuid(artifactsUUID);
375                 }
376             }
377         }
378         result = Either.left(groupDefinition);
379
380         return result;
381
382     }
383
384     @Override
385     public boolean isGroupExist(String groupName, boolean inTransaction) {
386
387         Either<List<GroupData>, TitanOperationStatus> eitherGroup = null;
388         try {
389             Map<String, Object> properties = new HashMap<>();
390             properties.put(GraphPropertiesDictionary.NAME.getProperty(), groupName);
391
392             eitherGroup = titanGenericDao.getByCriteria(NodeTypeEnum.Group, properties, GroupData.class);
393             return eitherGroup.isLeft() && !eitherGroup.left().value().isEmpty();
394
395         } finally {
396             handleTransactionCommitRollback(inTransaction, eitherGroup);
397         }
398     }
399
400     protected Either<List<GroupDefinition>, StorageOperationStatus> getAllGroupsFromGraph(String componentId, NodeTypeEnum componentTypeEnum, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) {
401
402         List<GroupDefinition> groups = new ArrayList<>();
403
404         Either<List<ImmutablePair<GroupData, GraphEdge>>, StorageOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, GraphEdgeLabels.GROUP, NodeTypeEnum.Group,
405                 GroupData.class)
406                 .right()
407                 .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
408
409         if (childrenNodes.isRight()) {
410             StorageOperationStatus status = childrenNodes.right().value();
411             return Either.right(status);
412         }
413
414         List<ImmutablePair<GroupData, GraphEdge>> graphGroups = childrenNodes.left().value();
415
416         if (isEmpty(graphGroups)) {
417             return Either.right(StorageOperationStatus.NOT_FOUND);
418         }
419
420
421
422                 for (ImmutablePair<GroupData, GraphEdge> pair : graphGroups) {
423
424             String groupUniqueId = pair.left.getGroupDataDefinition().getUniqueId();
425             Either<GroupDefinition, StorageOperationStatus> groupRes = this.getGroupFromGraph(groupUniqueId, skipProperties, skipMembers, skipArtifacts);
426
427             if (groupRes.isRight()) {
428                 StorageOperationStatus status = groupRes.right().value();
429                 if (status == StorageOperationStatus.NOT_FOUND) {
430                     status = StorageOperationStatus.INVALID_ID;
431                 }
432                 return Either.right(status);
433             } else {
434                 groups.add(groupRes.left().value());
435             }
436
437         }
438
439         return Either.left(groups);
440     }
441
442     private StorageOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) {
443
444                 Either<List<GroupDefinition>, StorageOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, componentTypeEnum, true, true, false);
445                 if (allGroupsFromGraph.isRight()) {
446                         return allGroupsFromGraph.right().value();
447
448                 }
449
450         List<GroupDefinition> allGroups = allGroupsFromGraph.left().value();
451         if (isEmpty(allGroups)) {
452             return StorageOperationStatus.OK;
453         }
454
455         // Find all groups which contains this artifact id
456         List<GroupDefinition> associatedGroups = allGroups.stream().filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(oldArtifactId)).collect(Collectors.toList());
457
458         if (isNotEmpty(associatedGroups)) {
459
460             log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(GroupDataDefinition::getName).collect(Collectors.toList()), oldArtifactId);
461
462             UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId);
463             UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, newArtifact.getArtifactDataDefinition().getUniqueId());
464             Map<String, Object> props = new HashMap<>();
465             props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel());
466
467             for (GroupDefinition groupDefinition : associatedGroups) {
468                 UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId());
469
470                 Either<GraphRelation, StorageOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF)
471                         .right()
472                         .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
473                 log.trace("After dissociate group {} from artifact {}"  , groupDefinition.getName(), oldArtifactId);
474                 if (deleteRelation.isRight()) {
475                     StorageOperationStatus status = deleteRelation.right().value();
476                     if (status == StorageOperationStatus.NOT_FOUND) {
477                         status = StorageOperationStatus.INVALID_ID;
478                     }
479                     return status;
480                 }
481
482                 Either<GraphRelation, StorageOperationStatus> createRelation = titanGenericDao.createRelation(groupData, newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props)
483                         .right()
484                         .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
485                 log.trace("After associate group {} to artifact {}" , groupDefinition.getName(), newArtifact.getUniqueIdKey());
486                 if (createRelation.isRight()) {
487                     StorageOperationStatus status = createRelation.right().value();
488                     if (status == StorageOperationStatus.NOT_FOUND) {
489                         status = StorageOperationStatus.INVALID_ID;
490                     }
491                     return status;
492                 }
493             }
494
495         }
496         return StorageOperationStatus.OK;
497     }
498
499     @Override
500     public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction) {
501
502         StorageOperationStatus result = null;
503
504         try {
505             StorageOperationStatus status = this.dissociateAndAssociateGroupsFromArtifactOnGraph(componentId, componentTypeEnum, oldArtifactId, newArtifact);
506
507             if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
508                 return status;
509             }
510
511             result = StorageOperationStatus.OK;
512             return result;
513
514         } finally {
515             if (!inTransaction) {
516                 if (result == null || result != StorageOperationStatus.OK) {
517                     log.debug("Going to execute rollback on graph.");
518                     BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph");
519                     titanGenericDao.rollback();
520                 } else {
521                     log.debug("Going to execute commit on graph.");
522                     titanGenericDao.commit();
523                 }
524             }
525         }
526     }
527
528     private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs(String groupUniqueId) {
529
530         Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null;
531
532         Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF,
533                 NodeTypeEnum.ArtifactRef, ArtifactData.class);
534         if (childrenNodes.isRight()) {
535             TitanOperationStatus status = childrenNodes.right().value();
536             if (status == TitanOperationStatus.NOT_FOUND) {
537                 status = TitanOperationStatus.OK;
538             }
539             result = Either.right(status);
540
541         } else {
542
543             List<ImmutablePair<String, String>> artifactsList = new ArrayList<>();
544             List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value();
545             if (list != null) {
546                 for (ImmutablePair<ArtifactData, GraphEdge> pair : list) {
547                     ArtifactData artifactData = pair.getKey();
548                     String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId();
549                     String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID();
550                     ImmutablePair<String, String> artifact = new ImmutablePair<>(uniqueId, UUID);
551                     artifactsList.add(artifact);
552                 }
553             }
554
555             log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList);
556             result = Either.left(artifactsList);
557         }
558
559         return result;
560
561     }
562
563     @Override
564     public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property) {
565
566         StorageOperationStatus result = null;
567         String innerType = property.getSchema() == null ? null : property.getSchema().getProperty() == null ? null : property.getSchema().getProperty().getType();
568         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
569         Either<Object, Boolean> isValid = null;
570         if (allDataTypes.isRight()) {
571             TitanOperationStatus status = allDataTypes.right().value();
572             log.debug("Failed to fetch data types from cache. Status is {}. ", status);
573             result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
574         }
575         if(result == null){
576             isValid = propertyOperation.validateAndUpdatePropertyValue(property.getType(), property.getValue(), innerType, allDataTypes.left().value());
577             if(isValid.isRight()){
578                 log.debug("Failed to validate property value {}. Status is {}. ", property.getValue(), StorageOperationStatus.INVALID_PROPERTY);
579                 result =  StorageOperationStatus.INVALID_PROPERTY;
580             }
581         }
582         if(result == null){
583             String validValue = String.valueOf(isValid.left().value());
584             property.setValue(validValue);
585             result = StorageOperationStatus.OK;
586         }
587         return result;
588     }
589
590         public StorageOperationStatus updateGroupProperties(org.openecomp.sdc.be.model.Component containerComponent, String groupId, List<PropertyDataDefinition> propertiesToUpdate) {
591                 log.debug("#updateGroupProperties - updating the properties of group {} in component {}", groupId, containerComponent.getUniqueId());
592                 Optional<GroupDefinition> group = containerComponent.getGroupById(groupId);
593                 if (group.isPresent()){
594                         return titanDao.getVertexById(containerComponent.getUniqueId(), JsonParseFlagEnum.NoParse)
595                                         .either(containerVertex -> updateGroupProperties(containerVertex, group.get(), propertiesToUpdate),
596                                                         DaoStatusConverter::convertTitanStatusToStorageStatus);
597                 } else {
598                         throw new StorageException(StorageOperationStatus.NOT_FOUND, groupId);
599                 }
600         }
601
602         private StorageOperationStatus updateGroupProperties(GraphVertex container, GroupDefinition group, List<PropertyDataDefinition> propertiesToUpdate) {
603                 List<PropertyDataDefinition> groupProperties = group.getProperties();
604                 List<PropertyDataDefinition> updatedGroupProperties = updateGroupProperties(groupProperties, propertiesToUpdate);
605                 group.setProperties(updatedGroupProperties);
606                 return topologyTemplateOperation.updateGroupOfToscaElement(container, group);
607         }
608
609         private List<PropertyDataDefinition> updateGroupProperties(List<PropertyDataDefinition> currentGroupProperties, List<PropertyDataDefinition> toBeUpdatedProperties) {
610                 Map<String, PropertyDataDefinition> currPropsByName = MapUtil.toMap(currentGroupProperties, PropertyDataDefinition::getName);
611                 overrideCurrentPropertiesWithUpdatedProperties(currPropsByName, toBeUpdatedProperties);
612                 return new ArrayList<>(currPropsByName.values());
613         }
614
615         private void overrideCurrentPropertiesWithUpdatedProperties(Map<String, PropertyDataDefinition> currPropsByName, List<PropertyDataDefinition> toBeUpdatedProperties) {
616                 toBeUpdatedProperties.forEach(prop -> currPropsByName.put(prop.getName(), prop));
617         }
618
619 }