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