f2d0d94418f33311880dd28b0512c6384671677e
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / GroupBusinessLogic.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.components.impl;
22
23 import fj.data.Either;
24 import org.apache.commons.collections.CollectionUtils;
25 import org.apache.commons.collections.MapUtils;
26 import org.apache.commons.io.FilenameUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.lang3.math.NumberUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
31 import org.openecomp.sdc.be.components.impl.lock.LockingTransactional;
32 import org.openecomp.sdc.be.components.impl.policy.PolicyTargetsUpdateHandler;
33 import org.openecomp.sdc.be.components.utils.Utils;
34 import org.openecomp.sdc.be.components.validation.AccessValidations;
35 import org.openecomp.sdc.be.components.validation.ComponentValidations;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
38 import org.openecomp.sdc.be.config.ConfigurationManager;
39 import org.openecomp.sdc.be.dao.api.ActionStatus;
40 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
41 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
43 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
44 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
45 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
46 import org.openecomp.sdc.be.datatypes.enums.CreatedFrom;
47 import org.openecomp.sdc.be.info.ArtifactDefinitionInfo;
48 import org.openecomp.sdc.be.info.ArtifactTemplateInfo;
49 import org.openecomp.sdc.be.info.GroupDefinitionInfo;
50 import org.openecomp.sdc.be.model.*;
51 import org.openecomp.sdc.be.model.PropertyDefinition.GroupInstancePropertyValueUpdateBehavior;
52 import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames;
53 import org.openecomp.sdc.be.model.jsontitan.operations.GroupsOperation;
54 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
55 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
56 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
57 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
58 import org.openecomp.sdc.common.api.Constants;
59 import org.openecomp.sdc.common.log.wrappers.Logger;
60 import org.openecomp.sdc.common.util.ValidationUtils;
61 import org.openecomp.sdc.exception.ResponseFormat;
62 import org.springframework.beans.factory.annotation.Autowired;
63
64 import java.util.*;
65 import java.util.Map.Entry;
66 import java.util.regex.Pattern;
67 import java.util.stream.Collectors;
68
69 import static java.util.stream.Collectors.toList;
70 import static org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter.extractCapabilitiesFromGroups;
71 import static org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter.extractCapabilityPropertiesFromGroups;
72
73 @org.springframework.stereotype.Component("groupBusinessLogic")
74 public class GroupBusinessLogic extends BaseBusinessLogic {
75
76     public static final String GROUP_DELIMITER_REGEX = "\\.\\.";
77
78     public static final String INITIAL_VERSION = "1";
79
80     private static final String ADDING_GROUP = "AddingGroup";
81
82     private static final String CREATE_GROUP = "CreateGroup";
83
84     private static final String UPDATE_GROUP = "UpdateGroup";
85
86     private static final String GET_GROUP = "GetGroup";
87
88     private static final String DELETE_GROUP = "DeleteGroup";
89
90     private static final Logger log = Logger.getLogger(GroupBusinessLogic.class);
91     @Autowired
92     private AccessValidations accessValidations;
93
94     @javax.annotation.Resource
95     @Autowired
96     private GroupsOperation groupsOperation;
97
98     @Autowired
99     PolicyTargetsUpdateHandler policyTargetsUpdateHandler;
100
101     private String getComponentTypeForResponse(org.openecomp.sdc.be.model.Component component) {
102         String componentTypeForResponse = "SERVICE";
103         if (component instanceof Resource) {
104             componentTypeForResponse = ((Resource) component).getResourceType().name();
105         }
106         return componentTypeForResponse;
107     }
108
109     /**
110      * Verify that the artifact members belongs to the component
111      *
112      * @param component
113      * @param artifacts
114      * @return
115      */
116     private Either<Boolean, ResponseFormat> verifyArtifactsBelongsToComponent(Component component, List<String> artifacts, String context) {
117
118         if (CollectionUtils.isEmpty(artifacts)) {
119             return Either.left(true);
120         }
121
122         Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
123         if (MapUtils.isEmpty(deploymentArtifacts)) {
124             BeEcompErrorManager.getInstance().logInvalidInputError(context, "No deployment artifact found under component " + component.getNormalizedName(), ErrorSeverity.INFO);
125             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
126         }
127
128         List<String> currentArtifacts = deploymentArtifacts.values().stream().map(ArtifactDefinition::getUniqueId).collect(toList());
129         log.debug("The deployment artifacts of component {} are {}", component.getNormalizedName(), deploymentArtifacts);
130         if (!currentArtifacts.containsAll(artifacts)) {
131             BeEcompErrorManager.getInstance().logInvalidInputError(context, "Not all artifacts belongs to component " + component.getNormalizedName(), ErrorSeverity.INFO);
132             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
133         }
134
135         return Either.left(true);
136
137     }
138
139     /**
140      * verify that the members are component instances of the component
141      *
142      * @param component
143      * @param groupMembers
144      * @param memberToscaTypes
145      * @return
146      */
147     private Either<Boolean, ResponseFormat> verifyComponentInstancesAreValidMembers(Component component, String groupName, Map<String, String> groupMembers, List<String> memberToscaTypes) {
148
149         if (MapUtils.isEmpty(groupMembers)) {
150             return Either.left(true);
151         }
152
153         if (CollectionUtils.isEmpty(memberToscaTypes)) {
154             return Either.left(true);
155         }
156
157         List<ComponentInstance> componentInstances = component.getComponentInstances();
158         if (CollectionUtils.isNotEmpty(componentInstances)) {
159             Map<String, ComponentInstance> compInstUidToCompInstMap = componentInstances.stream().collect(Collectors.toMap(ComponentInstance::getUniqueId, p -> p));
160
161             Set<String> allCompInstances = compInstUidToCompInstMap.keySet();
162
163             for (Entry<String, String> groupMember : groupMembers.entrySet()) {
164                 String compName = groupMember.getKey();
165                 String compUid = groupMember.getValue();
166
167                 if (!allCompInstances.contains(compUid)) {
168                     /*
169                      * %1 - member name %2 - group name %3 - VF name %4 - component type [VF ]
170                      */
171                     String componentTypeForResponse = getComponentTypeForResponse(component);
172
173                     BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Not all group members exists under the component", ErrorSeverity.INFO);
174                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, compName, groupName, component.getNormalizedName(), componentTypeForResponse));
175                 }
176             }
177         }
178
179         return Either.left(true);
180     }
181
182
183
184     /**
185      * Update GroupDefinition metadata
186      *
187      * @param componentId
188      * @param user
189      * @param componentType
190      * @param updatedGroup
191      * @param inTransaction
192      * @return
193      */
194     public Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(String componentId, User user, ComponentTypeEnum componentType, GroupDefinition updatedGroup, boolean inTransaction , boolean shouldLock) {
195
196         Either<GroupDefinition, ResponseFormat> result = null;
197         try {
198             // Validate user exist
199             validateUserExists(user.getUserId(), UPDATE_GROUP, inTransaction);
200             // Validate component exist
201             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, null);
202             if (validateComponent.isRight()) {
203                 result = Either.right(validateComponent.right().value());
204                 return result;
205             }
206             org.openecomp.sdc.be.model.Component component = validateComponent.left().value();
207             // validate we can work on component
208             Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, user.getUserId());
209             if (canWork.isRight()) {
210                 result = Either.right(canWork.right().value());
211                 return result;
212             }
213             List<GroupDefinition> currentGroups = component.getGroups();
214             if (CollectionUtils.isEmpty(currentGroups)) {
215                 log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
216                 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
217                 return result;
218             }
219             // Validate groups exists in the component
220             Optional<GroupDefinition> currentGroupOpt = currentGroups.stream().filter(g -> g.getUniqueId().equals(updatedGroup.getUniqueId())).findAny();
221             if (!currentGroupOpt.isPresent()) {
222                 log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
223                 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
224                 return result;
225             }
226             GroupDefinition currentGroup = currentGroupOpt.get();
227             if ( shouldLock ){
228                 Either<Boolean, ResponseFormat> lockResult = lockComponent(componentId, component, "Update GroupDefinition Metadata");
229                 if (lockResult.isRight()) {
230                     result = Either.right(lockResult.right().value());
231                     return result;
232                 }
233             }
234             // Validate group type is vfModule
235             if (currentGroup.getType().equals(Constants.GROUP_TOSCA_HEAT)) {
236                 log.error("Failed to update the metadata of group {}. Group type is {} and cannot be updated", currentGroup.getName(), currentGroup.getType());
237                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, updatedGroup.getType());
238                 result = Either.right(responseFormat);
239                 return result;
240             }
241             result = updateGroupMetadata(component, currentGroup, updatedGroup);
242             return result;
243
244         } finally {
245             if (result != null && result.isLeft()) {
246                 titanDao.commit();
247             } else {
248                 titanDao.rollback();
249             }
250             if (shouldLock) {
251                 graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
252             }
253         }
254     }
255
256     private Either<GroupDefinition, ResponseFormat> updateGroupMetadata(Component component, GroupDefinition currentGroup, GroupDefinition updatedGroup) {
257         String currentGroupName = currentGroup.getName();
258         Either<GroupDefinition, ResponseFormat> result = validateAndUpdateGroupMetadata(currentGroup, updatedGroup);
259
260         if (result.isRight()) {
261             log.debug("Failed to validate a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
262         }
263         if (result.isLeft()) {
264             result = updateGroup(component, currentGroup, currentGroupName);
265         }
266         return result;
267     }
268
269     private Either<GroupDefinition, ResponseFormat> updateGroup(Component component, GroupDefinition updatedGroup, String currentGroupName) {
270         Either<GroupDefinition, StorageOperationStatus> handleGroupRes;
271         Either<GroupDefinition, ResponseFormat> result = null;
272         if (updatedGroup.getName().equals(currentGroupName)) {
273             handleGroupRes = groupsOperation.updateGroup(component, updatedGroup);
274             if (handleGroupRes.isRight()) {
275                 log.debug("Failed to update a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
276                 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
277             }
278         } else {
279             StorageOperationStatus deleteStatus = groupsOperation.deleteGroup(component, currentGroupName);
280             if (deleteStatus != StorageOperationStatus.OK) {
281                 log.debug("Failed to delete the group {} from component {}. ", updatedGroup.getName(), component.getName());
282                 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteStatus)));
283             }
284             handleGroupRes = groupsOperation.addGroup(component, updatedGroup);
285             if (handleGroupRes.isRight()) {
286                 log.debug("Failed to add the group {} to component {}. ", updatedGroup.getName(), component.getName());
287                 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
288             }
289         }
290         if (result == null) {
291             result = Either.left(updatedGroup);
292         }
293         return result;
294     }
295
296     /**
297      * Validate and update GroupDefinition metadata
298      *
299      * @param currentGroup
300      * @param groupUpdate
301      * @return
302      **/
303     private Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
304         // Check if to update, and update GroupDefinition name.
305         Either<Boolean, ResponseFormat> response = validateAndUpdateGroupName(currentGroup, groupUpdate);
306         if (response.isRight()) {
307             ResponseFormat errorResponse = response.right().value();
308             return Either.right(errorResponse);
309         }
310
311         // Do not allow to update GroupDefinition version directly.
312         String versionUpdated = groupUpdate.getVersion();
313         String versionCurrent = currentGroup.getVersion();
314         if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
315             log.info("update Group: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
316         }
317
318         return Either.left(currentGroup);
319     }
320
321     /**
322      * Validate and update GroupDefinition name
323      *
324      * @param currentGroup
325      * @param groupUpdate
326      * @return
327      */
328     private Either<Boolean, ResponseFormat> validateAndUpdateGroupName(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
329         String nameUpdated = groupUpdate.getName();
330         String nameCurrent = currentGroup.getName();
331         if (!nameCurrent.equals(nameUpdated)) {
332             Either<Boolean, ResponseFormat> validatNameResponse = validateGroupName(currentGroup.getName(), groupUpdate.getName() ,true);
333             if (validatNameResponse.isRight()) {
334                 ResponseFormat errorRespons = validatNameResponse.right().value();
335                 return Either.right(errorRespons);
336             }
337             currentGroup.setName(groupUpdate.getName());
338         }
339         return Either.left(true);
340     }
341
342     /**
343      * Validate that group name to update is valid (same as current group name except for middle part). For example: Current group name: MyResource..MyDesc..Module-1 Group to update: MyResource..MyDesc2..Module-1 Verify that only the second part
344      * MyDesc was changed.
345      *
346      * @param currentGroupName
347      * @param groupUpdateName
348      * @return
349      */
350     private Either<Boolean, ResponseFormat> validateGroupName(String currentGroupName, String groupUpdateName , boolean isforceNameModification) {
351         try {
352             // Check if the group name is in old format.
353             if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupUpdateName).matches()) {
354                 log.error("Group name {} is in old format", groupUpdateName);
355                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME, groupUpdateName));
356             }
357
358             // Check that name pats 1 and 3 did not changed (only the second
359             // part can be changed)
360             // But verify before that the current group format is the new one
361             if (!Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(currentGroupName).matches()) {
362                 String[] split1 = currentGroupName.split(GROUP_DELIMITER_REGEX);
363                 String currentResourceName = split1[0];
364                 String currentCounter = split1[2];
365
366                 String[] split2 = groupUpdateName.split(GROUP_DELIMITER_REGEX);
367                 String groupUpdateResourceName = split2[0];
368                 String groupUpdateCounter = split2[2];
369                 if (!isforceNameModification){            //if not forced ,allow name prefix&suffix validation [no changes]
370                     if (!currentResourceName.equals(groupUpdateResourceName)) {
371                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentResourceName));
372                     }
373
374                     if (!currentCounter.equals(groupUpdateCounter)) {
375                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentCounter));
376                     }
377                 }
378
379             }
380
381             return Either.left(true);
382         } catch (Exception e) {
383             log.error("Error valiadting group name", e);
384             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
385         }
386     }
387
388
389     /**
390      * associate artifacts to a given group
391      *
392      * @param componentId
393      * @param userId
394      * @param componentType
395      * @param inTransaction
396      * @return
397      */
398     public Either<GroupDefinitionInfo, ResponseFormat> getGroupWithArtifactsById(ComponentTypeEnum componentType, String componentId, String groupId, String userId, boolean inTransaction) {
399
400         Either<GroupDefinitionInfo, ResponseFormat> result = null;
401
402         // Validate user exist
403         validateUserExists(userId, GET_GROUP, true);
404         // Validate component exist
405         org.openecomp.sdc.be.model.Component component = null;
406
407         try {
408             ComponentParametersView componentParametersView = new ComponentParametersView();
409             componentParametersView.disableAll();
410             componentParametersView.setIgnoreGroups(false);
411             componentParametersView.setIgnoreArtifacts(false);
412             componentParametersView.setIgnoreUsers(false);
413
414             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
415             if (validateComponent.isRight()) {
416                 result = Either.right(validateComponent.right().value());
417                 return result;
418             }
419             component = validateComponent.left().value();
420
421             Either<GroupDefinition, StorageOperationStatus> groupEither = findGroupOnComponent(component, groupId);
422
423             if (groupEither.isRight()) {
424                 log.debug("Faild to find group {} under component {}", groupId, component.getUniqueId());
425                 BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "group  " + groupId + " not found under component " + component.getUniqueId(), ErrorSeverity.INFO);
426                 String componentTypeForResponse = getComponentTypeForResponse(component);
427                 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupId, component.getSystemName(), componentTypeForResponse));
428                 return result;
429             }
430             GroupDefinition group = groupEither.left().value();
431
432             Boolean isBase = null;
433             List<GroupProperty> props = group.convertToGroupProperties();
434             if (props != null && !props.isEmpty()) {
435                 Optional<GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
436                 if (isBasePropOp.isPresent()) {
437                     GroupProperty propIsBase = isBasePropOp.get();
438                     isBase = Boolean.parseBoolean(propIsBase.getValue());
439
440                 } else {
441                     BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
442                 }
443             }
444
445             List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
446             List<ArtifactDefinition> artifactsFromComponent = new ArrayList<>();
447             List<String> artifactsIds = group.getArtifacts();
448
449             Map<String, ArtifactDefinition> deploymentArtifacts = null;
450             if (MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
451                 deploymentArtifacts = component.getDeploymentArtifacts().values().stream().collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, a -> a));
452             }
453
454             if (artifactsIds != null && !artifactsIds.isEmpty()) {
455                 for (String id : artifactsIds) {
456                     if (deploymentArtifacts == null || !deploymentArtifacts.containsKey(id)) {
457                         log.debug("Failed to get artifact {} . Status is {} ", id, StorageOperationStatus.NOT_FOUND);
458                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND));
459                         result = Either.right(responseFormat);
460                         return result;
461                     }
462                     artifactsFromComponent.add(deploymentArtifacts.get(id));
463                 }
464                 if (!artifactsFromComponent.isEmpty()) {
465                     for (ArtifactDefinition artifactDefinition : artifactsFromComponent) {
466                         ArtifactDefinitionInfo artifactDefinitionInfo = new ArtifactDefinitionInfo(artifactDefinition);
467                         artifacts.add(artifactDefinitionInfo);
468                     }
469                 }
470
471             }
472             GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
473             resultInfo.setIsBase(isBase);
474             if (!artifacts.isEmpty()) {
475                 resultInfo.setArtifacts(artifacts);
476             }
477             result = Either.left(resultInfo);
478
479             return result;
480
481         } finally {
482
483             if (!inTransaction) {
484
485                 if (result == null || result.isRight()) {
486                     log.debug("Going to execute rollback on create group.");
487                     titanDao.rollback();
488                 } else {
489                     log.debug("Going to execute commit on create group.");
490                     titanDao.commit();
491                 }
492
493             }
494
495         }
496
497     }
498
499     private Either<GroupDefinition, StorageOperationStatus> findGroupOnComponent(Component component, String groupId) {
500
501         Either<GroupDefinition, StorageOperationStatus> result = null;
502         if (CollectionUtils.isNotEmpty(component.getGroups())) {
503             Optional<GroupDefinition> foundGroup = component.getGroups().stream().filter(g -> g.getUniqueId().equals(groupId)).findFirst();
504             if (foundGroup.isPresent()) {
505                 result = Either.left(foundGroup.get());
506             }
507         }
508         if (result == null) {
509             result = Either.right(StorageOperationStatus.NOT_FOUND);
510         }
511         return result;
512     }
513
514     public Either<Boolean, ResponseFormat> validateGenerateVfModuleGroupNames(List<ArtifactTemplateInfo> allGroups, String resourceSystemName, int startGroupCounter) {
515         Either<Boolean, ResponseFormat> validateGenerateGroupNamesRes = Either.left(true);
516         Collections.sort(allGroups, ArtifactTemplateInfo::compareByGroupName);
517         for (ArtifactTemplateInfo group : allGroups) {
518             Either<String, ResponseFormat> validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), startGroupCounter++);
519             if (validateGenerateGroupNameRes.isRight()) {
520                 validateGenerateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value());
521                 break;
522             }
523             group.setGroupName(validateGenerateGroupNameRes.left().value());
524         }
525         return validateGenerateGroupNamesRes;
526     }
527
528     /**
529      * Generate module name from resourceName, description and counter
530      *
531      * @param resourceSystemName
532      * @param description
533      * @param groupCounter
534      * @return
535      */
536     private Either<String, ResponseFormat> validateGenerateVfModuleGroupName(String resourceSystemName, String description, int groupCounter) {
537         Either<String, ResponseFormat> validateGenerateGroupNameRes;
538         if (resourceSystemName != null && description != null && Pattern.compile(Constants.MODULE_DESC_PATTERN).matcher(description).matches()) {
539             final String fileName = description.replaceAll(GROUP_DELIMITER_REGEX, "\\.");
540             validateGenerateGroupNameRes = Either.left(String.format(Constants.MODULE_NAME_FORMAT, resourceSystemName, FilenameUtils.removeExtension(fileName), groupCounter));
541         } else {
542             validateGenerateGroupNameRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME));
543         }
544         return validateGenerateGroupNameRes;
545     }
546
547     Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNames(Map<String, GroupDefinition> groups, String resourceSystemName) {
548
549         Map<String, GroupDefinition> updatedNamesGroups = new HashMap<>();
550         Either<Map<String, GroupDefinition>, ResponseFormat> result = Either.left(updatedNamesGroups);
551         for (Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
552             GroupDefinition curGroup = groupEntry.getValue();
553             String groupType = curGroup.getType();
554             String groupName = groupEntry.getKey();
555             int counter;
556             String description;
557             Either<String, ResponseFormat> newGroupNameRes;
558             if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(groupName).matches()) {
559
560                 if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupEntry.getKey()).matches()) {
561                     counter = Integer.parseInt(groupEntry.getKey().split(Constants.MODULE_NAME_DELIMITER)[1]);
562                     description = curGroup.getDescription();
563                 } else {
564                     counter = getNextVfModuleNameCounter(updatedNamesGroups);
565                     description = groupName;
566                 }
567                 newGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, description, counter);
568                 if (newGroupNameRes.isRight()) {
569                     log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
570                     result = Either.right(newGroupNameRes.right().value());
571                     break;
572                 }
573                 groupName = newGroupNameRes.left().value();
574                 curGroup.setName(groupName);
575             }
576             updatedNamesGroups.put(groupName, curGroup);
577         }
578         return result;
579     }
580
581     public int getNextVfModuleNameCounter(Map<String, GroupDefinition> groups) {
582         int counter = 0;
583         if (groups != null && !groups.isEmpty()) {
584             counter = getNextVfModuleNameCounter(groups.values());
585         }
586         return counter;
587     }
588
589     public int getNextVfModuleNameCounter(Collection<GroupDefinition> groups) {
590         int counter = 0;
591         if (groups != null && !groups.isEmpty()) {
592             List<Integer> counters = groups.stream().filter(group -> Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(group.getName()).matches() || Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(group.getName()).matches())
593                     .map(group -> Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1])).collect(toList());
594             counter = (counters == null || counters.isEmpty()) ? 0 : counters.stream().max(Integer::compare).get() + 1;
595         }
596         return counter;
597     }
598
599     public Either<List<GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesOnGraph(List<GroupDefinition> groups, Component component) {
600         List<GroupDefinition> updatedGroups = new ArrayList<>();
601         Either<List<GroupDefinition>, ResponseFormat> result = Either.left(updatedGroups);
602
603         for (GroupDefinition group : groups) {
604             String groupType = group.getType();
605             String oldGroupName = group.getName();
606             String newGroupName;
607             Either<String, ResponseFormat> newGroupNameRes;
608             int counter;
609             if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(oldGroupName).matches()) {
610                 counter = Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]);
611                 newGroupNameRes = validateGenerateVfModuleGroupName(component.getSystemName(), group.getDescription(), counter);
612                 if (newGroupNameRes.isRight()) {
613                     log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
614                     result = Either.right(newGroupNameRes.right().value());
615                     break;
616                 }
617                 newGroupName = newGroupNameRes.left().value();
618                 group.setName(newGroupName);
619
620             }
621             updatedGroups.add(group);
622
623         }
624
625         result = Either.left(updatedGroups);
626         return result;
627     }
628
629
630     public Either<GroupDefinitionInfo, ResponseFormat> getGroupInstWithArtifactsById(ComponentTypeEnum componentType, String componentId, String componentInstanceId, String groupInstId, String userId, boolean inTransaction) {
631         Either<GroupDefinitionInfo, ResponseFormat> result = null;
632
633         // Validate user exist
634         validateUserExists(userId, UPDATE_GROUP, true);
635         // Validate component exist
636         org.openecomp.sdc.be.model.Component component = null;
637
638         try {
639             ComponentParametersView componentParametersView = new ComponentParametersView();
640             componentParametersView.disableAll();
641             componentParametersView.setIgnoreUsers(false);
642             componentParametersView.setIgnoreComponentInstances(false);
643             componentParametersView.setIgnoreArtifacts(false);
644
645             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
646             if (validateComponent.isRight()) {
647                 result = Either.right(validateComponent.right().value());
648                 return result;
649             }
650             component = validateComponent.left().value();
651             Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceRes = findComponentInstanceAndGroupInstanceOnComponent(component, componentInstanceId, groupInstId);
652
653             if (findComponentInstanceAndGroupInstanceRes.isRight()) {
654                 log.debug("Failed to get group {} . Status is {} ", groupInstId, findComponentInstanceAndGroupInstanceRes.right().value());
655                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findComponentInstanceAndGroupInstanceRes.right().value()));
656                 result = Either.right(responseFormat);
657                 return result;
658             }
659
660             GroupInstance group = findComponentInstanceAndGroupInstanceRes.left().value().getRight();
661
662             Boolean isBase = null;
663             List<? extends GroupProperty> props = group.convertToGroupInstancesProperties();
664             if (props != null && !props.isEmpty()) {
665                 Optional<? extends GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
666                 if (isBasePropOp.isPresent()) {
667                     GroupProperty propIsBase = isBasePropOp.get();
668                     isBase = Boolean.parseBoolean(propIsBase.getValue());
669
670                 } else {
671                     BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
672                 }
673             }
674
675             List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
676             List<String> artifactsIds = group.getArtifacts();
677             if (artifactsIds != null && !artifactsIds.isEmpty()) {
678
679                 List<ComponentInstance> instances = component.getComponentInstances();
680                 if (instances != null) {
681                     Optional<ComponentInstance> findFirst = instances.stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst();
682                     if (findFirst.isPresent()) {
683                         ComponentInstance ci = findFirst.get();
684                         Map<String, ArtifactDefinition> deploymentArtifacts = ci.getDeploymentArtifacts();
685                         for (String id : artifactsIds) {
686                             Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
687                             if (artOp.isPresent()) {
688                                 artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
689                             }
690                         }
691                         List<String> instArtifactsIds = group.getGroupInstanceArtifacts();
692                         for (String id : instArtifactsIds) {
693                             Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
694                             if (artOp.isPresent()) {
695                                 artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
696                             }
697                         }
698                     }
699
700                 }
701             }
702             GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
703             resultInfo.setIsBase(isBase);
704             if (!artifacts.isEmpty()) {
705                 resultInfo.setArtifacts(artifacts);
706             }
707             result = Either.left(resultInfo);
708
709             return result;
710
711         } finally {
712
713             if (!inTransaction) {
714
715                 if (result == null || result.isRight()) {
716                     log.debug("Going to execute rollback on create group.");
717                     titanDao.rollback();
718                 } else {
719                     log.debug("Going to execute commit on create group.");
720                     titanDao.commit();
721                 }
722
723             }
724
725         }
726     }
727
728     private Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceOnComponent(Component component, String componentInstanceId, String groupInstId) {
729
730         Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> result = null;
731         if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
732             Optional<GroupInstance> foundGroup;
733             Optional<ComponentInstance> foundComponent = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst();
734             if (foundComponent.isPresent() && CollectionUtils.isNotEmpty(foundComponent.get().getGroupInstances())) {
735                 foundGroup = foundComponent.get().getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstId)).findFirst();
736                 if (foundGroup.isPresent()) {
737                     result = Either.left(new ImmutablePair<>(foundComponent.get(), foundGroup.get()));
738                 }
739             }
740         }
741         if (result == null) {
742             result = Either.right(StorageOperationStatus.NOT_FOUND);
743         }
744         return result;
745     }
746
747     private Either<Boolean, ResponseFormat> validateMinMaxAndInitialCountPropertyLogic(Map<PropertyNames, String> newValues, Map<PropertyNames, String> currValues, Map<PropertyNames, String> parentValues) {
748
749         Either<Boolean, ResponseFormat> result;
750         for (Entry<PropertyNames, String> entry : newValues.entrySet()) {
751             PropertyNames currPropertyName = entry.getKey();
752             if (currPropertyName == PropertyNames.MIN_INSTANCES) {
753                 String minValue = parentValues.get(PropertyNames.MIN_INSTANCES);
754                 String maxValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
755                 result = validateValueInRange(new ImmutablePair<>(currPropertyName, entry.getValue()), new ImmutablePair<>(PropertyNames.MIN_INSTANCES, minValue),
756                         new ImmutablePair<>(PropertyNames.MAX_INSTANCES, maxValue));
757                 if (result.isRight()) {
758                     return result;
759                 }
760             } else if (currPropertyName == PropertyNames.INITIAL_COUNT) {
761                 String minValue = newValues.containsKey(PropertyNames.MIN_INSTANCES) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.MIN_INSTANCES);
762                 String maxValue = newValues.containsKey(PropertyNames.MAX_INSTANCES) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.MAX_INSTANCES);
763                 result = validateValueInRange(new ImmutablePair<>(currPropertyName, entry.getValue()), new ImmutablePair<>(PropertyNames.MIN_INSTANCES, minValue),
764                         new ImmutablePair<>(PropertyNames.MAX_INSTANCES, maxValue));
765                 if (result.isRight()) {
766                     return result;
767                 }
768             } else if (currPropertyName == PropertyNames.MAX_INSTANCES) {
769                 String minValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
770                 String maxValue = parentValues.get(PropertyNames.MAX_INSTANCES);
771                 result = validateValueInRange(new ImmutablePair<>(currPropertyName, entry.getValue()), new ImmutablePair<>(PropertyNames.MIN_INSTANCES, minValue),
772                         new ImmutablePair<>(PropertyNames.MAX_INSTANCES, maxValue));
773                 if (result.isRight()) {
774                     return result;
775                 }
776             }
777         }
778         return Either.left(true);
779     }
780
781     private Either<Boolean, ResponseFormat> validateValueInRange(ImmutablePair<PropertyNames, String> newValue, ImmutablePair<PropertyNames, String> min, ImmutablePair<PropertyNames, String> max) {
782         Either<Boolean, ResponseFormat> result;
783         final String warnMessage = "Failed to validate {} as property value of {}. It must be not higher than {}, and not lower than {}.";
784         int newValueInt = parseIntValue(newValue.getValue(), newValue.getKey());
785         int minInt = parseIntValue(min.getValue(), min.getKey());
786         int maxInt = parseIntValue(max.getValue(), max.getKey());
787         if (newValueInt < 0 || minInt < 0 || maxInt < 0) {
788             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY));
789         } else if (newValueInt < minInt || newValueInt > maxInt) {
790             log.debug(warnMessage, newValue.getValue(), newValue.getKey().getPropertyName(), min.getValue(), max.getValue());
791             result = Either
792                     .right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_MIN_MAX_INSTANCES_PROPERTY_VALUE, newValue.getKey().getPropertyName(), maxInt == Integer.MAX_VALUE ? Constants.UNBOUNDED : max.getValue(), min.getValue()));
793         } else {
794             result = Either.left(true);
795         }
796         return result;
797     }
798
799     private int parseIntValue(String value, PropertyNames propertyName) {
800         int result;
801         if (propertyName == PropertyNames.MAX_INSTANCES) {
802             result = convertIfUnboundMax(value);
803         } else if (NumberUtils.isNumber(value)) {
804             result = Integer.parseInt(value);
805         } else {
806             result = -1;
807         }
808         return result;
809     }
810
811     /**
812      * validates received new property values and updates group instance in case of success
813      *
814      * @param oldGroupInstance
815      * @param newProperties
816      * @return
817      */
818     public Either<GroupInstance, ResponseFormat> validateAndUpdateGroupInstancePropertyValues(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
819
820         Either<GroupInstance, ResponseFormat> actionResult = null;
821         Either<GroupInstance, StorageOperationStatus> updateGroupInstanceResult = null;
822         Either<List<GroupInstanceProperty>, ResponseFormat> validateRes = validateReduceGroupInstancePropertiesBeforeUpdate(oldGroupInstance, newProperties);
823         if (validateRes.isRight()) {
824             log.debug("Failed to validate group instance {} properties before update. ", oldGroupInstance.getName());
825             actionResult = Either.right(validateRes.right().value());
826         }
827         if (actionResult == null) {
828             List<GroupInstanceProperty> validatedReducedNewProperties = validateRes.left().value();
829             updateGroupInstanceResult = groupsOperation.updateGroupInstancePropertyValuesOnGraph(componentId, instanceId, oldGroupInstance, validatedReducedNewProperties);
830             if (updateGroupInstanceResult.isRight()) {
831                 log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
832                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateGroupInstanceResult.right().value())));
833             }
834         }
835         if (actionResult == null) {
836             actionResult = Either.left(updateGroupInstanceResult.left().value());
837         }
838         return actionResult;
839     }
840
841     private Either<List<GroupInstanceProperty>, ResponseFormat> validateReduceGroupInstancePropertiesBeforeUpdate(GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
842
843         Either<Boolean, ResponseFormat> validationRes = null;
844         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult;
845         Map<String, GroupInstanceProperty> existingProperties = oldGroupInstance.convertToGroupInstancesProperties().stream().collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
846         Map<PropertyNames, String> newPropertyValues = new EnumMap<>(PropertyNames.class);
847         List<GroupInstanceProperty> reducedProperties = new ArrayList<>();
848         String currPropertyName;
849         try {
850             for (GroupInstanceProperty currNewProperty : newProperties) {
851                 currPropertyName = currNewProperty.getName();
852                 validationRes = handleAndAddProperty(reducedProperties, newPropertyValues, currNewProperty, existingProperties.get(currPropertyName));
853                 if (validationRes.isRight()) {
854                     log.debug("Failed to handle property {} of group instance {}. ", currPropertyName, oldGroupInstance.getName());
855                     break;
856                 }
857             }
858             if (validationRes == null || validationRes.isLeft()) {
859                 Map<PropertyNames, String> existingPropertyValues = new EnumMap<>(PropertyNames.class);
860                 Map<PropertyNames, String> parentPropertyValues = new EnumMap<>(PropertyNames.class);
861                 fillValuesAndParentValuesFromExistingProperties(existingProperties, existingPropertyValues, parentPropertyValues);
862                 validationRes = validateMinMaxAndInitialCountPropertyLogic(newPropertyValues, existingPropertyValues, parentPropertyValues);
863             }
864             if (validationRes.isLeft()) {
865                 actionResult = Either.left(reducedProperties);
866             } else {
867                 actionResult = Either.right(validationRes.right().value());
868             }
869         } catch (Exception e) {
870             log.error("Exception occured during validation and reducing group instance properties. The message is {}", e.getMessage(), e);
871             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
872         }
873         return actionResult;
874     }
875
876     private void fillValuesAndParentValuesFromExistingProperties(Map<String, GroupInstanceProperty> existingProperties, Map<PropertyNames, String> propertyValues, Map<PropertyNames, String> parentPropertyValues) {
877         PropertyNames[] allPropertyNames = PropertyNames.values();
878         for (PropertyNames name : allPropertyNames) {
879             if (isUpdatable(name)) {
880                 propertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getValue()));
881                 parentPropertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getParentValue()));
882             }
883         }
884     }
885
886     private Either<Boolean, ResponseFormat> handleAndAddProperty(List<GroupInstanceProperty> reducedProperties, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty currNewProperty, GroupInstanceProperty currExistingProperty) {
887
888         Either<Boolean, ResponseFormat> validationRes = null;
889         String currPropertyName = currNewProperty.getName();
890         PropertyNames propertyName = PropertyNames.findName(currPropertyName);
891         try {
892             if (currExistingProperty == null) {
893                 log.warn("The value of property with the name {} cannot be updated. The property not found on group instance. ", currPropertyName);
894             } else if (isUpdatable(propertyName)) {
895                 validationRes = validateAndUpdatePropertyValue(currNewProperty, currExistingProperty);
896                 if (validationRes.isRight()) {
897                     log.debug("Failed to validate property value {} of property {}. ", currNewProperty.getValue(), currPropertyName);
898                 } else {
899                     addPropertyUpdatedValues(reducedProperties, propertyName, newPropertyValues, currNewProperty, currExistingProperty);
900                 }
901             } else {
902                 validateImmutableProperty(currExistingProperty, currNewProperty);
903             }
904             if (validationRes == null) {
905                 validationRes = Either.left(true);
906             }
907         } catch (Exception e) {
908             log.error("Exception occured during handle and adding property. The message is {}", e.getMessage(), e);
909             validationRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
910         }
911         return validationRes;
912     }
913
914     private boolean isUpdatable(PropertyNames updatablePropertyName) {
915         return updatablePropertyName != null && updatablePropertyName.getUpdateBehavior().getLevelNumber() >= GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL.getLevelNumber();
916     }
917
918     private void addPropertyUpdatedValues(List<GroupInstanceProperty> reducedProperties, PropertyNames propertyName, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
919
920         String newValue = newProperty.getValue();
921         if (!newValue.equals(String.valueOf(existingProperty.getValue()))) {
922             newProperty.setValueUniqueUid(existingProperty.getValueUniqueUid());
923             reducedProperties.add(newProperty);
924         }
925         if (!isEmptyMinInitialCountValue(propertyName, newValue)) {
926             newPropertyValues.put(propertyName, newValue);
927         }
928     }
929
930     private boolean isEmptyMinInitialCountValue(PropertyNames propertyName, String newValue) {
931         boolean result = false;
932         if ((propertyName == PropertyNames.MIN_INSTANCES || propertyName == PropertyNames.INITIAL_COUNT) && !NumberUtils.isNumber(newValue)) {
933             result = true;
934         }
935         return result;
936     }
937
938     private int convertIfUnboundMax(String value) {
939
940         int result;
941         if (!NumberUtils.isNumber(value)) {
942             result = Integer.MAX_VALUE;
943         } else {
944             result = Integer.parseInt(value);
945         }
946         return result;
947     }
948
949     private Either<Boolean, ResponseFormat> validateAndUpdatePropertyValue(GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
950
951         Either<Boolean, ResponseFormat> validationRes = null;
952         String parentValue = existingProperty.getParentValue();
953
954         newProperty.setParentValue(parentValue);
955         if (StringUtils.isEmpty(newProperty.getValue())) {
956             newProperty.setValue(parentValue);
957         }
958         if (StringUtils.isEmpty(existingProperty.getValue())) {
959             existingProperty.setValue(parentValue);
960         }
961         StorageOperationStatus status = groupOperation.validateAndUpdatePropertyValue(newProperty);
962         if (status != StorageOperationStatus.OK) {
963             log.debug("Failed to validate property value {} of property with name {}. Status is {}. ", newProperty.getValue(), newProperty.getName(), status);
964             validationRes = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
965         }
966         if (validationRes == null) {
967             validationRes = Either.left(true);
968         }
969         return validationRes;
970     }
971
972     private void validateImmutableProperty(GroupProperty oldProperty, GroupProperty newProperty) {
973         if (oldProperty.getValue() == null && newProperty.getValue() != null || oldProperty.getValue() != null && !oldProperty.getValue().equals(newProperty.getValue())) {
974             log.warn("The value of property with the name {} cannot be updated on service level. Going to ignore new property value {}. ", oldProperty.getName(), newProperty.getValue());
975         }
976     }
977
978     @LockingTransactional
979     public GroupDefinition createGroup(String componentId, ComponentTypeEnum componentTypeEnum, String groupType,
980                                        String userId) {
981
982         Component component = accessValidations.validateUserCanWorkOnComponent(componentId, componentTypeEnum, userId, CREATE_GROUP);
983
984         validateGroupTypePerComponent(groupType, component);
985
986         GroupTypeDefinition groupTypeDefinition = groupTypeOperation.getLatestGroupTypeByType(groupType, false)
987                 .left()
988                 .on(se -> onGroupTypeNotFound(component));
989
990         boolean hasExistingGroups = CollectionUtils.isNotEmpty(component.getGroups());
991         GroupDefinition groupDefinition = new GroupDefinition();
992         groupDefinition.setType(groupType);
993
994         //find next valid counter
995         int nextCounter = 0;
996         if (hasExistingGroups) {
997             nextCounter = getNewGroupCounter(component);
998         }
999         String name = TopologyTemplateOperation.buildSubComponentName(component.getName(), groupType, nextCounter);
1000         groupDefinition.setName(name);
1001         groupDefinition.setDescription(groupTypeDefinition.getDescription());
1002         groupDefinition.setInvariantName(name);
1003         groupDefinition.setCreatedFrom(CreatedFrom.UI);
1004
1005         //Add default type properties
1006         List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
1007         List<GroupProperty> properties = groupTypeProperties.stream()
1008                 .map(GroupProperty::new)
1009                 .collect(toList());
1010         groupDefinition.convertFromGroupProperties(properties);
1011
1012         groupDefinition.convertCapabilityDefinitions(groupTypeDefinition.getCapabilities());
1013
1014         List<GroupDefinition> gdList;
1015         if (toscaOperationFacade.canAddGroups(componentId)) {
1016             gdList = addGroups(component, Arrays.asList(groupDefinition), false)
1017                     .left()
1018                     .on(this::onFailedGroupDBOperation);
1019         } else {
1020             //createGroups also creates an edge and vertex to store group data
1021             gdList = createGroups(component, Arrays.asList(groupDefinition), false)
1022                     .left()
1023                     .on(this::onFailedGroupDBOperation);
1024         }
1025         return gdList.get(0);
1026     }
1027
1028     private void validateGroupTypePerComponent(String groupType, Component component) {
1029         String specificType = component.getComponentMetadataDefinition().getMetadataDataDefinition().getActualComponentType();
1030         if (!component.isTopologyTemplate()) {
1031             throw new ComponentException(ActionStatus.GROUP_TYPE_ILLEGAL_PER_COMPONENT, groupType,
1032                     specificType);
1033         }
1034         Map<String, Set<String>> excludedGroupTypesMap = ConfigurationManager.getConfigurationManager().getConfiguration()
1035                 .getExcludedGroupTypesMapping();
1036
1037         if (MapUtils.isNotEmpty(excludedGroupTypesMap) && StringUtils.isNotEmpty(specificType)) {
1038             Set<String> excludedGroupTypesPerComponent = excludedGroupTypesMap.get(specificType);
1039             if (excludedGroupTypesPerComponent!=null && excludedGroupTypesPerComponent.contains(groupType)) {
1040                 throw new ComponentException(ActionStatus.GROUP_TYPE_ILLEGAL_PER_COMPONENT, groupType, specificType);
1041             }
1042         }
1043     }
1044
1045     private int getNewGroupCounter(Component component) {
1046         List<String> existingNames = component.getGroups()
1047                 .stream()
1048                 .map(GroupDataDefinition::getName)
1049                 .collect(toList());
1050         List<String> existingIds = component.getGroups()
1051                 .stream()
1052                 .map(GroupDataDefinition::getUniqueId)
1053                 .collect(toList());
1054         existingIds.addAll(existingNames);
1055
1056         return Utils.getNextCounter(existingIds);
1057     }
1058
1059     @LockingTransactional
1060     public GroupDefinition updateGroup(String componentId, ComponentTypeEnum componentTypeEnum, String groupId,
1061                                        String userId, GroupDefinition updatedGroup) {
1062         Component component = accessValidations.validateUserCanWorkOnComponent(componentId, componentTypeEnum, userId, UPDATE_GROUP);
1063
1064         GroupDefinition existingGroup = findGroupOnComponent(component, groupId)
1065                 .left()
1066                 .on(se -> onGroupNotFoundInComponentError(component, groupId));
1067
1068         String existingGroupName = existingGroup.getName();
1069         String updatedGroupName = updatedGroup.getName();
1070         assertNewNameIsValidAndUnique(existingGroupName, updatedGroupName, component);
1071         existingGroup.setName(updatedGroupName);
1072
1073         return updateGroup(component, existingGroup, existingGroupName)
1074                 .left()
1075                 .on(this::onFailedUpdateGroupDBOperation);
1076     }
1077
1078     private void assertNewNameIsValidAndUnique(String currentGroupName, String updatedGroupName, Component component) {
1079         if (!ValidationUtils.validateResourceInstanceNameLength(updatedGroupName)) {
1080             throw new ComponentException(ActionStatus.EXCEEDS_LIMIT, "Group Name", ValidationUtils.RSI_NAME_MAX_LENGTH.toString());
1081         }
1082         if (!ValidationUtils.validateResourceInstanceName(updatedGroupName)) {
1083             throw new ComponentException(ActionStatus.INVALID_VF_MODULE_NAME, updatedGroupName);
1084         }
1085         if (!ComponentValidations.validateNameIsUniqueInComponent(currentGroupName, updatedGroupName, component)) {
1086             throw new ComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, "Group", updatedGroupName);
1087         }
1088     }
1089
1090     @LockingTransactional
1091     public GroupDefinition deleteGroup(String componentId, ComponentTypeEnum componentTypeEnum, String groupId,
1092                                        String userId) {
1093         Component component = accessValidations.validateUserCanWorkOnComponent(componentId, componentTypeEnum, userId, DELETE_GROUP);
1094
1095         GroupDefinition groupDefinition = findGroupOnComponent(component, groupId)
1096                 .left()
1097                 .on(se -> onGroupNotFoundInComponentError(component, groupId));
1098
1099         List<GroupDefinition> gdList = deleteGroups(component, java.util.Arrays.asList(groupDefinition))
1100                 .left()
1101                 .on(this::onFailedGroupDBOperation);
1102
1103         updatePolicyTargetReferencingDeletedGroup(groupId, component);
1104         return gdList.get(0);
1105     }
1106
1107     private List<GroupDefinition> onFailedGroupDBOperation(ResponseFormat responseFormat) {
1108         titanDao.rollback();
1109         throw new ComponentException(responseFormat);
1110     }
1111
1112     private GroupDefinition onFailedUpdateGroupDBOperation(ResponseFormat responseFormat) {
1113         titanDao.rollback();
1114         throw new ComponentException(responseFormat);
1115     }
1116
1117     private GroupDefinition onGroupNotFoundInComponentError(Component component, String groupId) {
1118         throw new ComponentException(ActionStatus.GROUP_IS_MISSING, groupId,
1119                 component.getSystemName(), getComponentTypeForResponse(component));
1120     }
1121
1122     private GroupTypeDefinition onGroupTypeNotFound(Component component) {
1123         throw new ComponentException(ActionStatus.GROUP_TYPE_IS_INVALID, component.getSystemName(),
1124                 component.getComponentType().toString());
1125     }
1126
1127     private void updatePolicyTargetReferencingDeletedGroup(String groupId, Component component) {
1128         log.debug("#updatePolicyTargetReferencingDeletedGroup - removing all component {} policy targets referencing group {}", component.getUniqueId(), groupId);
1129         ActionStatus actionStatus = policyTargetsUpdateHandler.removePoliciesTargets(component, groupId, PolicyTargetType.GROUPS);
1130         if (ActionStatus.OK != actionStatus) {
1131             titanDao.rollback();
1132             throw new ComponentException(actionStatus, groupId);
1133         }
1134     }
1135
1136
1137     public Either<List<GroupDefinition>, ResponseFormat> createGroups(Component component, final List<GroupDefinition> groupDefinitions, boolean fromCsar) {
1138
1139         Map<String, GroupDataDefinition> groups = new HashMap<>();
1140         Either<List<GroupDefinition>, ResponseFormat> result = null;
1141         Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
1142         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
1143         if (allDataTypes.isRight()) {
1144             TitanOperationStatus status = allDataTypes.right().value();
1145             BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
1146             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
1147
1148         }
1149
1150         // handle groups and convert to tosca data
1151         if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
1152             for (GroupDefinition groupDefinition : groupDefinitions) {
1153                 Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, groupDefinition, allDataTypes.left().value());
1154                 if (handleGroupRes.isRight()) {
1155                     result = Either.right(handleGroupRes.right().value());
1156                     break;
1157                 }
1158                 GroupDefinition handledGroup = handleGroupRes.left().value();
1159                 groups.put(handledGroup.getName(), new GroupDataDefinition(handledGroup));
1160
1161             }
1162         }
1163         if (result == null) {
1164             createGroupsResult = groupsOperation.createGroups(component, groups);
1165             if (createGroupsResult.isRight()) {
1166                 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
1167             }
1168         }
1169         if (result == null) {
1170             addCalculatedCapabilitiesWithPropertiesToComponent(component, groupDefinitions, fromCsar);
1171         }
1172         if (result == null) {
1173             result = Either.left(groupDefinitions);
1174         }
1175         return result;
1176     }
1177
1178     private void updateCalculatedCapabilitiesWithPropertiesOnComponent(Component component, final List<GroupDefinition> groupDefinitions, boolean fromCsar) {
1179         groupDefinitions.forEach(GroupDefinition::updateEmptyCapabilitiesOwnerFields);
1180         StorageOperationStatus status = groupsOperation.updateCalculatedCapabilitiesWithProperties(component.getUniqueId(),
1181                 extractCapabilitiesFromGroups(groupDefinitions), extractCapabilityPropertiesFromGroups(groupDefinitions, fromCsar));
1182         if(status != StorageOperationStatus.OK){
1183             log.error("#updateCalculatedCapabilitiesWithPropertiesOnComponent - failed to update the groups' calculated capabilities with the properties on the component {}. ", component.getUniqueId());
1184             rollbackWithException(componentsUtils.convertFromStorageResponse(status));
1185         }
1186     }
1187
1188     private void addCalculatedCapabilitiesWithPropertiesToComponent(Component component, final List<GroupDefinition> groupDefinitions, boolean fromCsar) {
1189         groupDefinitions.forEach(GroupDefinition::updateEmptyCapabilitiesOwnerFields);
1190         StorageOperationStatus status = groupsOperation.addCalculatedCapabilitiesWithProperties(component.getUniqueId(),
1191                 extractCapabilitiesFromGroups(groupDefinitions), extractCapabilityPropertiesFromGroups(groupDefinitions, fromCsar));
1192         if(status != StorageOperationStatus.OK){
1193             log.error("#addCalculatedCapabilitiesWithPropertiesToComponent - failed to add the groups' calculated capabilities with the properties to the component {}. ", component.getUniqueId());
1194             rollbackWithException(componentsUtils.convertFromStorageResponse(status));
1195         }
1196     }
1197
1198     private void deleteCalculatedCapabilitiesWithPropertiesFromComponent(Component component, final List<GroupDefinition> groupDefinitions) {
1199         StorageOperationStatus status = groupsOperation.deleteCalculatedCapabilitiesWithProperties(component.getUniqueId(), groupDefinitions);
1200         if(status != StorageOperationStatus.OK){
1201             log.error("#deleteCalculatedCapabilitiesWithPropertiesFromComponent - failed to remove the groups' calculated capabilities with the properties from the component {}. ", component.getUniqueId());
1202             rollbackWithException(componentsUtils.convertFromStorageResponse(status));
1203         }
1204     }
1205
1206     public Either<List<GroupDefinition>, ResponseFormat> addGroups(Component component, final List<GroupDefinition> groupDefinitions, boolean fromCsar) {
1207
1208         Either<List<GroupDefinition>, ResponseFormat> result = null;
1209         Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
1210         List<GroupDataDefinition> groups = new ArrayList<>();
1211
1212         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
1213         if (allDataTypes.isRight()) {
1214             TitanOperationStatus status = allDataTypes.right().value();
1215             BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
1216             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
1217
1218         }
1219
1220         // handle groups and convert to tosca data
1221         if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
1222             for (GroupDefinition groupDefinition : groupDefinitions) {
1223                 Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, groupDefinition, allDataTypes.left().value());
1224                 if (handleGroupRes.isRight()) {
1225                     result = Either.right(handleGroupRes.right().value());
1226                     break;
1227                 }
1228                 GroupDefinition handledGroup = handleGroupRes.left().value();
1229                 groups.add(new GroupDataDefinition(handledGroup));
1230             }
1231         }
1232         if (result == null) {
1233             createGroupsResult = groupsOperation.addGroups(component, groups);
1234             if (createGroupsResult.isRight()) {
1235                 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
1236             }
1237         }
1238         if (result == null) {
1239             addCalculatedCapabilitiesWithPropertiesToComponent(component, groupDefinitions, fromCsar);
1240         }
1241         if (result == null) {
1242             result = Either.left(groupDefinitions);
1243         }
1244         return result;
1245     }
1246
1247     public Either<List<GroupDefinition>, ResponseFormat> deleteGroups(Component component, List<GroupDefinition> groupDefinitions) {
1248
1249         Either<List<GroupDefinition>, StorageOperationStatus> deleteGroupsResult;
1250
1251         deleteGroupsResult = groupsOperation.deleteGroups(component, groupDefinitions.stream().map(GroupDataDefinition::new).collect(toList()));
1252         if (deleteGroupsResult.isRight()) {
1253             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteGroupsResult.right().value())));
1254         } else {
1255             deleteCalculatedCapabilitiesWithPropertiesFromComponent(component, groupDefinitions);
1256         }
1257         return Either.left(deleteGroupsResult.left().value());
1258     }
1259
1260     /**
1261      * Update specific group version
1262      * @param fromCsar TODO
1263      *
1264      */
1265     public Either<List<GroupDefinition>, ResponseFormat> updateGroups(Component component, List<GroupDefinition> groupDefinitions, boolean fromCsar) {
1266
1267         Either<List<GroupDefinition>, ResponseFormat> result = null;
1268         Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult;
1269
1270         createGroupsResult = groupsOperation.updateGroups(component, groupDefinitions.stream().map(GroupDataDefinition::new).collect(toList()), true);
1271         if (createGroupsResult.isRight()) {
1272             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
1273         }
1274         if (result == null) {
1275             updateCalculatedCapabilitiesWithPropertiesOnComponent(component, groupDefinitions, fromCsar);
1276         }
1277         if (result == null) {
1278             result = Either.left(groupDefinitions);
1279         }
1280         return result;
1281     }
1282
1283     private Either<GroupDefinition, ResponseFormat> handleGroup(Component component, GroupDefinition groupDefinition, Map<String, DataTypeDefinition> allDAtaTypes) {
1284
1285         log.trace("Going to create group {}", groupDefinition);
1286         // 3. verify group not already exist
1287         String groupDefinitionName = groupDefinition.getName();
1288         if (groupExistsInComponent(groupDefinitionName, component)) {
1289             String componentTypeForResponse = getComponentTypeForResponse(component);
1290             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ALREADY_EXIST, groupDefinitionName, component.getNormalizedName(), componentTypeForResponse));
1291         }
1292         // 4. verify type of group exist
1293         String groupType = groupDefinition.getType();
1294         if (StringUtils.isEmpty(groupType)) {
1295             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupDefinitionName));
1296         }
1297         Either<GroupTypeDefinition, StorageOperationStatus> getGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType, true);
1298         if (getGroupType.isRight()) {
1299             StorageOperationStatus status = getGroupType.right().value();
1300             if (status == StorageOperationStatus.NOT_FOUND) {
1301                 BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "group type " + groupType + " cannot be found", ErrorSeverity.INFO);
1302                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, groupType));
1303             } else {
1304                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1305             }
1306         }
1307         // 6. verify the component instances type are allowed according to
1308         // the member types in the group type
1309         GroupTypeDefinition groupTypeDefinition = getGroupType.left().value();
1310
1311         Either<Boolean, ResponseFormat> areValidMembers = verifyComponentInstancesAreValidMembers(component, groupDefinitionName, groupDefinition.getMembers(), groupTypeDefinition.getMembers());
1312
1313         if (areValidMembers.isRight()) {
1314             ResponseFormat responseFormat = areValidMembers.right().value();
1315             return Either.right(responseFormat);
1316         }
1317         // 7. verify the artifacts belongs to the component
1318         Either<Boolean, ResponseFormat> areValidArtifacts = verifyArtifactsBelongsToComponent(component, groupDefinition.getArtifacts(), CREATE_GROUP);
1319         if (areValidArtifacts.isRight()) {
1320             ResponseFormat responseFormat = areValidArtifacts.right().value();
1321             return Either.right(responseFormat);
1322         }
1323         List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
1324
1325         List<GroupProperty> properties = groupDefinition.convertToGroupProperties();
1326         List<GroupProperty> updatedGroupTypeProperties = new ArrayList<>();
1327         if (CollectionUtils.isNotEmpty(properties)) {
1328             if (CollectionUtils.isEmpty(groupTypeProperties)) {
1329                 BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "group type does not have properties", ErrorSeverity.INFO);
1330                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.MATCH_NOT_FOUND))));
1331             }
1332
1333             Map<String, PropertyDefinition> groupTypePropertiesMap = groupTypeProperties.stream().collect(Collectors.toMap(PropertyDefinition::getName, p -> p));
1334
1335             Either<GroupProperty, TitanOperationStatus> addPropertyResult;
1336             int i = 1;
1337             for (GroupProperty prop : properties) {
1338                 addPropertyResult = handleProperty(prop, groupTypePropertiesMap.get(prop.getName()), i, allDAtaTypes, groupType);
1339                 if (addPropertyResult.isRight()) {
1340                     BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "failed to validate property", ErrorSeverity.INFO);
1341                     return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyResult.right().value()))));
1342                 }
1343                 updatedGroupTypeProperties.add(addPropertyResult.left().value());
1344
1345                 i++;
1346             }
1347         }
1348
1349         if (groupDefinition.getUniqueId() == null) {
1350             String uid = UniqueIdBuilder.buildGroupingUid(component.getUniqueId(), groupDefinitionName);
1351             groupDefinition.setUniqueId(uid);
1352         }
1353         groupDefinition.convertFromGroupProperties(updatedGroupTypeProperties);
1354         groupDefinition.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
1355         groupDefinition.setGroupUUID(UniqueIdBuilder.generateUUID());
1356         groupDefinition.setVersion(INITIAL_VERSION);
1357         groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
1358
1359         return Either.left(groupDefinition);
1360     }
1361
1362     private static boolean groupExistsInComponent(String groupDefinitionName, Component component) {
1363         boolean found = false;
1364         List<GroupDefinition> groups = component.getGroups();
1365         if (CollectionUtils.isNotEmpty(groups)) {
1366             found = groups.stream().filter(p -> p.getName().equalsIgnoreCase(groupDefinitionName)).findFirst().orElse(null) != null;
1367         }
1368         return found;
1369     }
1370
1371     private Either<GroupProperty, TitanOperationStatus> handleProperty(GroupProperty groupProperty, PropertyDefinition prop, Integer index, Map<String, DataTypeDefinition> allDataTypes, String groupType) {
1372
1373         if (prop == null) {
1374             return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
1375         }
1376
1377         String propertyType = prop.getType();
1378         String value = groupProperty.getValue();
1379
1380         Either<String, TitanOperationStatus> checkInnerType = propertyOperation.checkInnerType(prop);
1381         if (checkInnerType.isRight()) {
1382             TitanOperationStatus status = checkInnerType.right().value();
1383             return Either.right(status);
1384         }
1385
1386         String innerType = checkInnerType.left().value();
1387
1388         log.debug("Before validateAndUpdatePropertyValue");
1389         Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes);
1390         log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
1391
1392         String newValue = value;
1393         if (isValid.isRight()) {
1394             Boolean res = isValid.right().value();
1395             if (!res) {
1396                 return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
1397             }
1398         } else {
1399             Object object = isValid.left().value();
1400             if (object != null) {
1401                 newValue = object.toString();
1402             }
1403         }
1404
1405         String uniqueId = shouldReconstructUniqueId(groupType) ? UniqueIdBuilder.buildGroupPropertyValueUid(prop.getUniqueId(), index)
1406                 : prop.getUniqueId();
1407
1408         groupProperty.setUniqueId(uniqueId);
1409         groupProperty.setValue(newValue);
1410         groupProperty.setType(prop.getType());
1411         groupProperty.setDefaultValue(prop.getDefaultValue());
1412         groupProperty.setDescription(prop.getDescription());
1413         groupProperty.setSchema(prop.getSchema());
1414         groupProperty.setPassword(prop.isPassword());
1415         groupProperty.setParentUniqueId(prop.getUniqueId());
1416
1417         log.debug("Before adding property value to graph {}", groupProperty);
1418
1419         return Either.left(groupProperty);
1420     }
1421
1422     // For old groups we want to leave indexing of property
1423     // For new groups we just need the types
1424     private boolean shouldReconstructUniqueId(String groupType) {
1425         return Constants.GROUP_TOSCA_HEAT.equals(groupType) || Constants.DEFAULT_GROUP_VF_MODULE.equals(groupType);
1426     }
1427
1428 }