Sync Integ to Master
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / GroupBusinessLogic.java
index de571b0..63b72b9 100644 (file)
 
 package org.openecomp.sdc.be.components.impl;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.utils.Utils;
+import org.openecomp.sdc.be.components.validation.AccessValidations;
+import org.openecomp.sdc.be.components.validation.ComponentValidations;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
+import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
@@ -69,2084 +60,1666 @@ import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
 import org.openecomp.sdc.be.model.jsontitan.operations.ArtifactsOperations;
 import org.openecomp.sdc.be.model.jsontitan.operations.GroupsOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.util.ValidationUtils;
 import org.openecomp.sdc.exception.ResponseFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
-import fj.data.Either;
+import static java.util.stream.Collectors.toList;
 
 @org.springframework.stereotype.Component("groupBusinessLogic")
 public class GroupBusinessLogic extends BaseBusinessLogic {
-       private static String ADDING_GROUP = "AddingGroup";
-
-       public static final String INITIAL_VERSION = "1";
-
-       private static final String CREATE_GROUP = "CreateGroup";
-
-       private static final String UPDATE_GROUP = "UpdateGroup";
-
-       private static final String GET_GROUP = "GetGroup";
-
-       private static Logger log = LoggerFactory.getLogger(GroupBusinessLogic.class.getName());
-
-       public GroupBusinessLogic() {
-
-       }
-
-       @javax.annotation.Resource
-       private GroupTypeOperation groupTypeOperation;
-
-       @Autowired
-       ArtifactsOperations artifactsOperation;
-
-       @Autowired
-       private GroupsOperation groupsOperation;
-       @Autowired
-       private ApplicationDataTypeCache dataTypeCache;
-
-       /**
-        * 
-        * 1. validate user exist
-        * 
-        * 2. validate component can be edited
-        * 
-        * 3. verify group not already exist
-        * 
-        * 4. verify type of group exist
-        * 
-        * 5. verify Component instances exist under the component
-        * 
-        * 6. verify the component instances type are allowed according to the member types in the group type
-        * 
-        * 7. verify the artifacts belongs to the component
-        * 
-        * @param componentId
-        * @param userId
-        * @param componentType
-        * @param groupDefinition
-        * @param inTransaction
-        * @return
-        */
-       /*
-        * public Either<GroupDefinition, ResponseFormat> createGroup(String componentId, String userId, ComponentTypeEnum componentType, GroupDefinition groupDefinition, boolean inTransaction) {
-        * 
-        * Either<GroupDefinition, ResponseFormat> result = null;
-        * 
-        * try { Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, CREATE_GROUP, inTransaction);
-        * 
-        * if (validateUserExists.isRight()) { result = Either.right(validateUserExists.right().value()); return result; }
-        * 
-        * User user = validateUserExists.left().value(); // 5. check service/resource existence // 6. check service/resource check out // 7. user is owner of checkout state org.openecomp.sdc.be.model.Component component = null;
-        * 
-        * // String realComponentId = componentType == // ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId; String realComponentId = componentId;
-        * 
-        * ComponentParametersView componentParametersView = new ComponentParametersView(); componentParametersView.disableAll(); componentParametersView.setIgnoreGroups(false); componentParametersView.setIgnoreArtifacts(false);
-        * componentParametersView.setIgnoreUsers(false); componentParametersView.setIgnoreComponentInstances(false);
-        * 
-        * Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
-        * 
-        * if (validateComponent.isRight()) { result = Either.right(validateComponent.right().value()); return result; } component = validateComponent.left().value(); Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component,
-        * userId); if (canWork.isRight()) { result = Either.right(canWork.right().value()); return result; }
-        * 
-        * result = this.createGroup(component, user, componentType, groupDefinition, inTransaction); return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * } }
-        */
-
-       private String getComponentTypeForResponse(org.openecomp.sdc.be.model.Component component) {
-               String componentTypeForResponse = "SERVICE";
-               if (component instanceof Resource) {
-                       componentTypeForResponse = ((Resource) component).getResourceType().name();
-               }
-               return componentTypeForResponse;
-       }
-
-       /**
-        * Verify that the artifact members belongs to the component
-        * 
-        * @param component
-        * @param artifacts
-        * @return
-        */
-       private Either<Boolean, ResponseFormat> verifyArtifactsBelongsToComponent(Component component, List<String> artifacts, String context) {
-
-               if (artifacts == null || true == artifacts.isEmpty()) {
-                       return Either.left(true);
-               }
-
-               Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
-               if (deploymentArtifacts == null || true == deploymentArtifacts.isEmpty()) {
-                       BeEcompErrorManager.getInstance().logInvalidInputError(context, "No deployment artifact found under component " + component.getNormalizedName(), ErrorSeverity.INFO);
-                       return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-               }
-
-               List<String> currentArtifacts = deploymentArtifacts.values().stream().map(p -> p.getUniqueId()).collect(Collectors.toList());
-               log.debug("The deployment artifacts of component {} are {}", component.getNormalizedName(), deploymentArtifacts);
-               if (false == currentArtifacts.containsAll(artifacts)) {
-                       BeEcompErrorManager.getInstance().logInvalidInputError(context, "Not all artifacts belongs to component " + component.getNormalizedName(), ErrorSeverity.INFO);
-                       return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-               }
-
-               return Either.left(true);
-
-       }
-
-       /**
-        * verify that the members are component instances of the component
-        * 
-        * @param component
-        * @param componentType
-        * @param groupMembers
-        * @param memberToscaTypes
-        * @return
-        */
-       private Either<Boolean, ResponseFormat> verifyComponentInstancesAreValidMembers(Component component, ComponentTypeEnum componentType, String groupName, String groupType, Map<String, String> groupMembers, List<String> memberToscaTypes) {
-
-               if (groupMembers == null || true == groupMembers.isEmpty()) {
-                       return Either.left(true);
-               }
-
-               if (memberToscaTypes == null || true == memberToscaTypes.isEmpty()) {
-                       return Either.left(true);
-               }
-
-               List<ComponentInstance> componentInstances = component.getComponentInstances();
-               if (componentInstances != null && false == componentInstances.isEmpty()) {
-                       Map<String, ComponentInstance> compInstUidToCompInstMap = componentInstances.stream().collect(Collectors.toMap(p -> p.getUniqueId(), p -> p));
-
-                       Set<String> allCompInstances = compInstUidToCompInstMap.keySet();
-
-                       for (Entry<String, String> groupMember : groupMembers.entrySet()) {
-                               String compName = groupMember.getKey();
-                               String compUid = groupMember.getValue();
-
-                               if (false == allCompInstances.contains(compUid)) {
-                                       /*
-                                        * %1 - member name %2 - group name %3 - VF name %4 - component type [VF ]
-                                        */
-                                       String componentTypeForResponse = getComponentTypeForResponse(component);
-
-                                       BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Not all group members exists under the component", ErrorSeverity.INFO);
-                                       return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, compName, groupName, component.getNormalizedName(), componentTypeForResponse));
-                               }
-                       }
-
-                       // ComponentOperation componentOperation = getComponentOperationByParentComponentType(componentType);
-                       // if (componentOperation instanceof ResourceOperation) {
-                       // ResourceOperation resourceOperation = (ResourceOperation) componentOperation;
-                       //
-                       // for (Entry<String, String> groupMember : groupMembers.entrySet()) {
-                       //
-                       // String componentInstName = groupMember.getKey();
-                       // String componentInstUid = groupMember.getValue();
-                       //
-                       // ComponentInstance componentInstance = compInstUidToCompInstMap.get(componentInstUid);
-                       // String componentUid = componentInstance.getComponentUid();
-                       // List<String> componentToscaNames = new ArrayList<>();
-                       // TitanOperationStatus status = resourceOperation.fillResourceDerivedListFromGraph(componentUid, componentToscaNames);
-                       // if (status != TitanOperationStatus.OK) {
-                       // BeEcompErrorManager.getInstance().logInternalFlowError(CREATE_GROUP, "Cannot find tosca list of component id " + componentUid, ErrorSeverity.ERROR);
-                       // return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-                       // }
-                       //
-                       // log.debug("The tosca names of component id {} are {}", componentUid, memberToscaTypes);
-                       //
-                       // boolean found = false;
-                       // for (String memberToscaType : memberToscaTypes) {
-                       // if (componentToscaNames.contains(memberToscaType)) {
-                       // found = true;
-                       // break;
-                       // }
-                       // }
-                       // if (found == false) {
-                       // BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP,
-                       // "No tosca types from " + memberToscaTypes + " can be found in the tosca list " + componentToscaNames + " of component " + componentInstance.getNormalizedName(), ErrorSeverity.INFO);
-                       // /*
-                       // * # %1 - member name # %2 - group name # %3 - group type
-                       // */
-                       // return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE, componentInstName, groupName, groupType));
-                       // } else {
-                       // log.debug("Component instance {} fits to one of the required tosca types", componentInstance.getNormalizedName());
-                       // }
-                       // }
-                       // } else {
-                       // BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Cannot find tosca list since it is not supported for product", ErrorSeverity.ERROR);
-                       // return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-                       // }
-
-               }
-
-               return Either.left(true);
-       }
-
-       /**
-        * Update specific group version
-        * 
-        * @param groupDefinition
-        * @param inTransaction
-        * @return
-        */
-       /*
-        * public Either<GroupDefinition, StorageOperationStatus> updateGroupVersion(GroupDefinition groupDefinition, boolean inTransaction) { Either<GroupDefinition, StorageOperationStatus> result = null; List<String> groupIdsToUpdateVersion = new
-        * ArrayList<>(); groupIdsToUpdateVersion.add(groupDefinition.getUniqueId()); Either<List<GroupDefinition>, StorageOperationStatus> updateGroupVersion = updateGroupVersion(groupIdsToUpdateVersion, inTransaction); if (updateGroupVersion.isLeft())
-        * { result = Either.left(updateGroupVersion.left().value().get(0)); } else { log.debug("Failed to update group version. Status is {} ", updateGroupVersion.right().value()); result = Either.right(updateGroupVersion.right().value()); } return
-        * result; }
-        */
-
-       /**
-        * Update list of groups versions
-        * 
-        * @param groupsUniqueId
-        * @param inTransaction
-        * @return
-        */
-       /*
-        * public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupVersion(List<String> groupsUniqueId, boolean inTransaction) {
-        * 
-        * Either<List<GroupDefinition>, StorageOperationStatus> result = null;
-        * 
-        * try {
-        * 
-        * result = groupOperation.updateGroupVersion(groupsUniqueId, true);
-        * 
-        * return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * }
-        * 
-        * }
-        */
-
-       /**
-        * Update GroupDefinition metadata
-        * 
-        * @param componentId
-        * @param user
-        * @param componentType
-        * @param updatedGroup
-        * @param inTransaction
-        * @return
-        */
-       public Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(String componentId, User user, ComponentTypeEnum componentType, GroupDefinition updatedGroup, boolean inTransaction , boolean shouldLock) {
-
-               Either<GroupDefinition, ResponseFormat> result = null;
-               try {
-                       // Validate user exist
-                       Either<User, ResponseFormat> validateUserExists = validateUserExists(user.getUserId(), UPDATE_GROUP, inTransaction);
-                       if (validateUserExists.isRight()) {
-                               result = Either.right(validateUserExists.right().value());
-                               return result;
-                       }
-                       // Validate component exist
-                       Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, null);
-                       if (validateComponent.isRight()) {
-                               result = Either.right(validateComponent.right().value());
-                               return result;
-                       }
-                       org.openecomp.sdc.be.model.Component component = validateComponent.left().value();
-                       // validate we can work on component
-                       Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, user.getUserId());
-                       if (canWork.isRight()) {
-                               result = Either.right(canWork.right().value());
-                               return result;
-                       }
-                       List<GroupDefinition> currentGroups = component.getGroups();
-                       if (CollectionUtils.isEmpty(currentGroups)) {
-                               log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
-                               return result;
-                       }
-                       // Validate groups exists in the component
-                       Optional<GroupDefinition> currentGroupOpt = currentGroups.stream().filter(g -> g.getUniqueId().equals(updatedGroup.getUniqueId())).findAny();
-                       if (!currentGroupOpt.isPresent()) {
-                               log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
-                               return result;
-                       }
-                       GroupDefinition currentGroup = currentGroupOpt.get();
-                       if ( shouldLock ){
-                               Either<Boolean, ResponseFormat> lockResult = lockComponent(componentId, component, "Update GroupDefinition Metadata");
-                               if (lockResult.isRight()) {
-                                       result = Either.right(lockResult.right().value());
-                                       return result;
-                               }
-                       }
-                       // Validate group type is vfModule
-                       if (!currentGroup.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
-                               log.error("Failed to update the metadata of group {}. Group type is {} and different then: {}", currentGroup.getName(), currentGroup.getType(), Constants.DEFAULT_GROUP_VF_MODULE);
-                               ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_TYPE, updatedGroup.getType());
-                               result = Either.right(responseFormat);
-                               return result;
-                       }
-                       result = updateGroupMetadata(component, currentGroup, updatedGroup);
-                       return result;
-
-               } finally {
-                       if (result.isLeft()) {
-                               titanDao.commit();
-                       } else {
-                               titanDao.rollback();
-                       }
-                       if( shouldLock )
-                               graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
-               }
-       }
-
-       private Either<GroupDefinition, ResponseFormat> updateGroupMetadata(Component component, GroupDefinition currentGroup, GroupDefinition updatedGroup) {
-               String currentGroupName = currentGroup.getName();
-               Either<GroupDefinition, ResponseFormat> result = validateAndUpdateGroupMetadata(currentGroup, updatedGroup);
-
-               if (result.isRight()) {
-                       log.debug("Failed to validate a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
-               }
-               if (result.isLeft()) {
-                       result = updateGroup(component, currentGroup, currentGroupName);
-               }
-               return result;
-       }
-
-       private Either<GroupDefinition, ResponseFormat> updateGroup(Component component, GroupDefinition updatedGroup, String currentGroupName) {
-               Either<GroupDefinition, StorageOperationStatus> handleGroupRes;
-               Either<GroupDefinition, ResponseFormat> result = null;
-               if (updatedGroup.getName().equals(currentGroupName)) {
-                       handleGroupRes = groupsOperation.updateGroup(component, updatedGroup);
-                       if (handleGroupRes.isRight()) {
-                               log.debug("Failed to update a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
-                       }
-               } else {
-                       StorageOperationStatus deleteStatus = groupsOperation.deleteGroup(component, currentGroupName);
-                       if (deleteStatus != StorageOperationStatus.OK) {
-                               log.debug("Failed to delete the group {} from component {}. ", updatedGroup.getName(), component.getName());
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteStatus)));
-                       }
-                       handleGroupRes = groupsOperation.addGroup(component, updatedGroup);
-                       if (handleGroupRes.isRight()) {
-                               log.debug("Failed to add the group {} to component {}. ", updatedGroup.getName(), component.getName());
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
-                       }
-               }
-               if (result == null) {
-                       result = Either.left(updatedGroup);
-               }
-               return result;
-       }
-
-       /**
-        * Validate and Update Group Property
-        * 
-        * @param componentId
-        * @param groupUniqueId
-        * @param user
-        * @param componentType
-        * @param groupPropertiesToUpdate
-        * @param inTransaction
-        * @return
-        */
-       public Either<List<GroupProperty>, ResponseFormat> validateAndUpdateGroupProperties(String componentId, String groupUniqueId, User user, ComponentTypeEnum componentType, List<GroupProperty> groupPropertiesToUpdate, boolean inTransaction) {
-
-               Either<List<GroupProperty>, ResponseFormat> result = Either.left(groupPropertiesToUpdate);
-               try {
-                       Optional<GroupDefinition> optionalGroupConnectedToVf = null;
-                       GroupDefinition currentGroup = null;
-                       StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentId, componentType.getNodeType());
-                       if (lockResult != StorageOperationStatus.OK) {
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult, componentType), componentId));
-                       }
-                       if (result.isLeft()) {
-                               // VF exist because lock succedded
-                               Resource vf = (Resource) toscaOperationFacade.getToscaElement(componentId).left().value();
-                               optionalGroupConnectedToVf =
-                                               // All groups on resource
-                                               vf.getGroups().stream().
-                                               // Filter in group sent is part of VF groups
-                                                               filter(e -> e.getUniqueId().equals(groupUniqueId)).
-                                                               // Collect
-                                                               findAny();
-                               if (!optionalGroupConnectedToVf.isPresent()) {
-                                       result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupUniqueId, vf.getName(), ComponentTypeEnum.RESOURCE.getValue()));
-                               }
-                       }
-
-                       if (result.isLeft()) {
-                               currentGroup = optionalGroupConnectedToVf.get();
-                               result = validateGroupPropertyAndResetEmptyValue(currentGroup, groupPropertiesToUpdate);
-                       }
-                       if (result.isLeft()) {
-                               result = updateGroupPropertiesValue(componentId, currentGroup, groupPropertiesToUpdate, inTransaction);
-                               if (result.isRight()) {
-                                       BeEcompErrorManager.getInstance().logBeSystemError("Update GroupProperties");
-                                       log.debug("failed to update Vf {}", componentId);
-                               }
-                       }
-
-               } catch (Exception e) {
-                       log.debug("Error in validateAndUpdateGroupProperty {}", e);
-                       result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-               } finally {
-                       graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
-               }
-               return result;
-       }
-
-       private void resetEmptyValueWithDefaults(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
-               Map<String, GroupProperty> originalProperties =
-                               // Stream of original properties from group
-                               originalGroup.convertToGroupProperties().stream().
-                               // Collecting to map with name as key
-                                               collect(Collectors.toMap(e -> e.getName(), e -> e));
-               for (GroupProperty gp : groupPropertiesToUpdate) {
-                       if (StringUtils.isEmpty(gp.getValue())) {
-                               gp.setValue(originalProperties.get(gp.getName()).getDefaultValue());
-                       }
-               }
-
-       }
-
-       private Either<List<GroupProperty>, ResponseFormat> validateGroupPropertyAndResetEmptyValue(GroupDefinition originalGroup, List<GroupProperty> groupPropertiesToUpdate) {
-
-               Either<List<GroupProperty>, ResponseFormat> ret = validateOnlyValueChanged(groupPropertiesToUpdate, originalGroup);
-               if (ret.isLeft()) {
-                       resetEmptyValueWithDefaults(groupPropertiesToUpdate, originalGroup);
-               }
-               if (ret.isLeft()) {
-                       // Validate Type Match Value
-                       Optional<StorageOperationStatus> optionalError =
-                                       // Stream of group properties
-                                       groupPropertiesToUpdate.stream().
-                                       // Validate each and map to returned Strorage status value
-                                                       map(e -> groupOperation.validateAndUpdatePropertyValue(e)).
-                                                       // Keep only failed result if there is such
-                                                       filter(e -> e != StorageOperationStatus.OK).
-                                                       // collect
-                                                       findFirst();
-                       if (optionalError.isPresent()) {
-                               ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(optionalError.get());
-                               ret = Either.right(componentsUtils.getResponseFormat(actionStatus));
-                       }
-
-               }
-               if (ret.isLeft()) {
-                       // Validate min max ect...
-                       ret = validatePropertyBusinessLogic(groupPropertiesToUpdate, originalGroup);
-               }
-
-               return ret;
-       }
-
-       private Either<List<GroupProperty>, ResponseFormat> validatePropertyBusinessLogic(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
-
-               Either<List<GroupProperty>, ResponseFormat> ret = Either.left(groupPropertiesToUpdate);
-
-               Map<PropertyNames, String> nameValueMap = new HashMap<>();
-               for (GroupProperty gp : groupPropertiesToUpdate) {
-                       // Filter out non special properties which does not have Enum
-                       final PropertyNames gpEnum = PropertyNames.findName(gp.getName());
-                       if (gpEnum != null) {
-                               nameValueMap.put(gpEnum, gp.getValue());
-                       }
-               }
-
-               if (!MapUtils.isEmpty(nameValueMap)) {
-
-                       if (nameValueMap.containsKey(PropertyNames.INITIAL_COUNT) || nameValueMap.containsKey(PropertyNames.MAX_INSTANCES) || nameValueMap.containsKey(PropertyNames.MIN_INSTANCES)) {
-
-                               Map<PropertyNames, String> oldValueMap = prepareMapWithOriginalProperties(originalGroup);
-
-                               Either<Boolean, ResponseFormat> eitherValid = validateMinMaxAndInitialCountPropertyLogicVF(nameValueMap, oldValueMap);
-                               if (eitherValid.isRight()) {
-                                       ret = Either.right(eitherValid.right().value());
-                               }
-                       }
-                       if (ret.isLeft() && (nameValueMap.containsKey(PropertyNames.VF_MODULE_DESCRIPTION) || nameValueMap.containsKey(PropertyNames.VF_MODULE_LABEL))) {
-
-                               Optional<ResponseFormat> optionalError =
-                                               // Stream of group Properties
-                                               groupPropertiesToUpdate.stream().
-                                               // Filter in only properties that needs text validation
-                                                               filter(e -> enumHasValueFilter(e.getName(), enumName -> PropertyNames.findName(enumName), PropertyNames.VF_MODULE_DESCRIPTION, PropertyNames.VF_MODULE_LABEL)).
-                                                               // validate text properties
-                                                               map(e -> validateFreeText(e)).
-                                                               // filter in only errors if exist
-                                                               filter(e -> e.isRight()).
-                                                               // map the Either value to the Error
-                                                               map(e -> e.right().value())
-                                                               // collect
-                                                               .findFirst();
-                               if (optionalError.isPresent()) {
-                                       ret = Either.right(optionalError.get());
-                               }
-
-                       }
-               }
-
-               return ret;
-       }
-
-       private Map<PropertyNames, String> prepareMapWithOriginalProperties(GroupDefinition originalGroup) {
-               Map<PropertyNames, String> oldValueMap = new HashMap<>();
-               PropertyNames[] propertiesToCheck = new PropertyNames[] { PropertyNames.INITIAL_COUNT, PropertyNames.MAX_INSTANCES, PropertyNames.MIN_INSTANCES };
-
-               for (GroupProperty gp : originalGroup.convertToGroupProperties()) {
-                       if (enumHasValueFilter(gp.getName(), enumName -> PropertyNames.findName(enumName), propertiesToCheck)) {
-                               oldValueMap.put(PropertyNames.findName(gp.getName()), gp.getValue());
-                       }
-               }
-               if (StringUtils.isEmpty(oldValueMap.get(PropertyNames.MAX_INSTANCES))) {
-                       oldValueMap.put(PropertyNames.MAX_INSTANCES, String.valueOf(Integer.MAX_VALUE));
-               }
-               return oldValueMap;
-       }
-
-       private Either<List<GroupProperty>, ResponseFormat> validateOnlyValueChanged(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
-
-               Either<List<GroupProperty>, ResponseFormat> ret = Either.left(groupPropertiesToUpdate);
-               if (CollectionUtils.isEmpty(groupPropertiesToUpdate)) {
-                       ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, StringUtils.EMPTY));
-               } else if (CollectionUtils.isEmpty(originalGroup.getProperties())) {
-                       ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, groupPropertiesToUpdate.get(NumberUtils.INTEGER_ZERO).getName()));
-               } else {
-                       Map<String, GroupProperty> namePropertyMap =
-                                       // Original Group Properties Stream
-                                       originalGroup.convertToGroupProperties().stream().
-                                       // Collect to map with name as key
-                                                       collect(Collectors.toMap(e -> e.getName(), e -> e));
-
-                       Optional<GroupProperty> optionalMissingProperty =
-                                       // Group Properties to be updated Stream
-                                       groupPropertiesToUpdate.stream().
-                                       // Filter in property that is not contained in original if there is such
-                                                       filter(e -> !namePropertyMap.containsKey(e.getName())).
-                                                       // collect
-                                                       findFirst();
-
-                       if (optionalMissingProperty.isPresent()) {
-                               ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, optionalMissingProperty.get().getName()));
-                       } else {
-                               Optional<GroupProperty> optionalNonValueChange =
-                                               // groups to be updated stream
-                                               groupPropertiesToUpdate.stream().
-                                               // filter in only properties with non-value (illegal) change
-                                                               filter(e -> !isOnlyGroupPropertyValueChanged(e, namePropertyMap.get(e.getName()))).
-                                                               // Collect
-                                                               findFirst();
-                               if (optionalNonValueChange.isPresent()) {
-                                       ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY, optionalNonValueChange.get().getName()));
-
-                               }
-                       }
-
-               }
-               return ret;
-       }
-
-       /**
-        * if groupProperty are the same or if only value is different returns true, otherwise returns false.
-        * 
-        * @param groupProperty
-        * @param groupProperty2
-        * @return
-        */
-       private boolean isOnlyGroupPropertyValueChanged(GroupProperty groupProperty, GroupProperty groupProperty2) {
-               // Create 2 duplicates for groupPropery and reset their values
-               Gson gson = new GsonBuilder().setPrettyPrinting().create();
-               try {
-                       GroupProperty groupPropertyDuplicate = new GroupProperty(groupProperty);
-                       groupPropertyDuplicate.setValue(null);
-                       groupPropertyDuplicate.setSchema(null);
-                       groupPropertyDuplicate.setParentUniqueId(null);
-                       // GroupProperty groupProperty2Duplicate = gson.fromJson(JsonParserUtils.jsonToString(groupProperty2), GroupProperty.class);
-                       GroupProperty groupProperty2Duplicate = new GroupProperty(groupProperty2);
-                       groupProperty2Duplicate.setValue(null);
-                       groupProperty2Duplicate.setSchema(null);
-                       groupProperty2Duplicate.setParentUniqueId(null);
-                       return groupPropertyDuplicate.equals(groupProperty2Duplicate) && StringUtils.equals(groupPropertyDuplicate.getValueUniqueUid(), groupProperty2Duplicate.getValueUniqueUid());
-               } catch (Exception e) {
-                       log.debug("Failed validate group properties. ", e);
-                       return false;
-               }
-       }
-
-       /**
-        * Validate and update GroupDefinition metadata
-        * 
-        * @param user
-        * @param currentGroup
-        * @param groupUpdate
-        * @return
-        **/
-       private Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
-               // Check if to update, and update GroupDefinition name.
-               Either<Boolean, ResponseFormat> response = validateAndUpdateGroupName(currentGroup, groupUpdate);
-               if (response.isRight()) {
-                       ResponseFormat errorResponse = response.right().value();
-                       return Either.right(errorResponse);
-               }
-
-               // Do not allow to update GroupDefinition version directly.
-               String versionUpdated = groupUpdate.getVersion();
-               String versionCurrent = currentGroup.getVersion();
-               if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
-                       log.info("update Group: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
-               }
-
-               return Either.left(currentGroup);
-       }
-
-       /**
-        * Validate and update GroupDefinition name
-        * 
-        * @param user
-        * @param currentGroup
-        * @param groupUpdate
-        * @return
-        */
-       private Either<Boolean, ResponseFormat> validateAndUpdateGroupName(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
-               String nameUpdated = groupUpdate.getName();
-               String nameCurrent = currentGroup.getName();
-               if (!nameCurrent.equals(nameUpdated)) {
-                       Either<Boolean, ResponseFormat> validatNameResponse = validateGroupName(currentGroup.getName(), groupUpdate.getName() ,true);
-                       if (validatNameResponse.isRight()) {
-                               ResponseFormat errorRespons = validatNameResponse.right().value();
-                               return Either.right(errorRespons);
-                       }
-                       currentGroup.setName(groupUpdate.getName());
-               }
-               return Either.left(true);
-       }
-
-       /**
-        * 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
-        * MyDesc was changed.
-        * 
-        * @param currentGroupName
-        * @param groupUpdateName
-        * @return
-        */
-       private Either<Boolean, ResponseFormat> validateGroupName(String currentGroupName, String groupUpdateName , boolean isforceNameModification) {
-               try {
-                       // Check if the group name is in old format.
-                       if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupUpdateName).matches()) {
-                               log.error("Group name {} is in old format", groupUpdateName);
-                               return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME, groupUpdateName));
-                       }
-
-                       // Check that name pats 1 and 3 did not changed (only the second
-                       // part can be changed)
-                       // But verify before that the current group format is the new one
-                       if (!Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(currentGroupName).matches()) {
-                               String[] split1 = currentGroupName.split("\\.\\.");
-                               String currentResourceName = split1[0];
-                               String currentCounter = split1[2];
-
-                               String[] split2 = groupUpdateName.split("\\.\\.");
-                               String groupUpdateResourceName = split2[0];
-                               String groupUpdateCounter = split2[2];
-                               if (!isforceNameModification){                  //if not forced ,allow name prefix&suffix validation [no changes]
-                                       if (!currentResourceName.equals(groupUpdateResourceName)) {
-                                               return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentResourceName));
-                                       }
-
-                                       if (!currentCounter.equals(groupUpdateCounter)) {
-                                               return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentCounter));
-                                       }
-                               }
-
-                       }
-
-                       return Either.left(true);
-               } catch (Exception e) {
-                       log.error("Error valiadting group name", e);
-                       return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-               }
-       }
-
-       /**
-        * associate artifacts to a given group
-        * 
-        * @param componentId
-        * @param userId
-        * @param componentType
-        * @param groups
-        * @param shouldLockComp
-        * @param inTransaction
-        * @return
-        */
-       /*
-        * public Either<List<GroupDefinition>, ResponseFormat> associateArtifactsToGroup(String componentId, String userId, ComponentTypeEnum componentType, List<GroupDefinition> groups, boolean shouldLockComp, boolean inTransaction) {
-        * 
-        * Either<List<GroupDefinition>, ResponseFormat> result = null;
-        * 
-        * if (shouldLockComp == true && inTransaction == true) { BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); // Cannot lock
-        * component since we are in a middle of another // transaction. ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; result = Either.right(componentsUtils.getResponseFormat(actionStatus)); return result; }
-        * 
-        * Component component = null; try {
-        * 
-        * if (groups == null || groups.isEmpty()) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); }
-        * 
-        * Either<Component, ResponseFormat> validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); if (validateGroupsBeforeUpdate.isRight()) { result =
-        * Either.right(validateGroupsBeforeUpdate.right().value()); return result; }
-        * 
-        * component = validateGroupsBeforeUpdate.left().value();
-        * 
-        * if (shouldLockComp) { Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, "Group - Associate Artifacts"); if (lockComponent.isRight()) { return Either.right(lockComponent.right().value()); } }
-        * 
-        * List<GroupDefinition> updatedGroups = new ArrayList<>();
-        * 
-        * List<GroupDefinition> componentGroups = component.getGroups();
-        * 
-        * // per group, associate to it the artifacts for (GroupDefinition groupDefinition : groups) {
-        * 
-        * GroupDefinition componentGroup = componentGroups.stream().filter(p -> p.getUniqueId().equals(groupDefinition.getUniqueId())).findFirst().orElse(null); if (componentGroup != null) { List<String> componentArtifacts =
-        * componentGroup.getArtifacts(); int artifactsSizeInGroup = componentArtifacts == null ? 0 : componentArtifacts.size(); if (artifactsSizeInGroup > 0) { List<String> artifactsToAssociate = groupDefinition.getArtifacts();
-        * 
-        * // if no artifcats sent if (artifactsToAssociate == null || true == artifactsToAssociate.isEmpty()) { continue; }
-        * 
-        * boolean isChanged = componentArtifacts.removeAll(artifactsToAssociate); if (isChanged) {// I.e. At least one artifact is already // associated to the group log.debug("Some of the artifacts already associated to group {}" ,
-        * groupDefinition.getUniqueId()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_ASSOCIATED, componentGroup.getName())); } } }
-        * 
-        * Either<GroupDefinition, StorageOperationStatus> associateArtifactsToGroup = groupOperation.associateArtifactsToGroup(groupDefinition.getUniqueId(), groupDefinition.getArtifacts(), true);
-        * 
-        * if (associateArtifactsToGroup.isRight()) { ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateArtifactsToGroup.right().value()); result = Either.right(componentsUtils.getResponseFormat(actionStatus));
-        * log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); return result; } updatedGroups.add(associateArtifactsToGroup.left().value());
-        * 
-        * }
-        * 
-        * result = Either.left(updatedGroups); return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * // unlock resource if (shouldLockComp && component != null) { graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); }
-        * 
-        * } }
-        */
-
-       /*
-        * public Either<List<GroupDefinition>, ResponseFormat> associateMembersToGroup(String componentId, String userId, ComponentTypeEnum componentType, List<GroupDefinition> groups, boolean shouldLockComp, boolean inTransaction) {
-        * 
-        * Either<List<GroupDefinition>, ResponseFormat> result = null;
-        * 
-        * if (shouldLockComp == true && inTransaction == true) { BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); // Cannot lock
-        * component since we are in a middle of another // transaction. ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; result = Either.right(componentsUtils.getResponseFormat(actionStatus)); return result; }
-        * 
-        * Component component = null; try {
-        * 
-        * if (groups == null || groups.isEmpty()) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); }
-        * 
-        * Either<Component, ResponseFormat> validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); if (validateGroupsBeforeUpdate.isRight()) { result =
-        * Either.right(validateGroupsBeforeUpdate.right().value()); return result; }
-        * 
-        * component = validateGroupsBeforeUpdate.left().value();
-        * 
-        * if (shouldLockComp) { Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, "Group - Associate Members"); if (lockComponent.isRight()) { return Either.right(lockComponent.right().value()); } }
-        * 
-        * List<GroupDefinition> updatedGroups = new ArrayList<>();
-        * 
-        * // per group, associate to it the members for (GroupDefinition groupDefinition : groups) {
-        * 
-        * Either<GroupDefinition, StorageOperationStatus> associateMembersToGroup = groupOperation.associateMembersToGroup(groupDefinition.getUniqueId(), groupDefinition.getMembers(), true);
-        * 
-        * if (associateMembersToGroup.isRight()) { ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateMembersToGroup.right().value()); result = Either.right(componentsUtils.getResponseFormat(actionStatus));
-        * log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); return result; } else { updatedGroups.add(associateMembersToGroup.left().value()); }
-        * 
-        * }
-        * 
-        * result = Either.left(updatedGroups); return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * // unlock resource if (shouldLockComp && component != null) { graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); }
-        * 
-        * } }
-        */
-
-       /**
-        * associate artifacts to a given group
-        * 
-        * @param componentId
-        * @param userId
-        * @param componentType
-        * @param groups
-        * @param shouldLockComp
-        * @param inTransaction
-        * @return
-        */
-       public Either<GroupDefinitionInfo, ResponseFormat> getGroupWithArtifactsById(ComponentTypeEnum componentType, String componentId, String groupId, String userId, boolean inTransaction) {
-
-               Either<GroupDefinitionInfo, ResponseFormat> result = null;
-
-               // Validate user exist
-               Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, UPDATE_GROUP, true);
-
-               if (validateUserExists.isRight()) {
-                       result = Either.right(validateUserExists.right().value());
-                       return result;
-               }
-
-               // Validate component exist
-               org.openecomp.sdc.be.model.Component component = null;
-               String realComponentId = componentId;
-
-               try {
-                       ComponentParametersView componentParametersView = new ComponentParametersView();
-                       componentParametersView.disableAll();
-                       componentParametersView.setIgnoreGroups(false);
-                       componentParametersView.setIgnoreArtifacts(false);
-                       componentParametersView.setIgnoreUsers(false);
-
-                       Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
-                       if (validateComponent.isRight()) {
-                               result = Either.right(validateComponent.right().value());
-                               return result;
-                       }
-                       component = validateComponent.left().value();
-
-                       Either<GroupDefinition, StorageOperationStatus> groupEither = findGroupOnComponent(component, groupId);
-
-                       if (groupEither.isRight()) {
-                               log.debug("Faild to find group {} under component {}", groupId, component.getUniqueId());
-                               BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "group  " + groupId + " not found under component " + component.getUniqueId(), ErrorSeverity.INFO);
-                               String componentTypeForResponse = getComponentTypeForResponse(component);
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupId, component.getSystemName(), componentTypeForResponse));
-                               return result;
-                       }
-                       GroupDefinition group = groupEither.left().value();
-
-                       Boolean isBase = null;// Constants.IS_BASE;
-                       List<GroupProperty> props = group.convertToGroupProperties();
-                       if (props != null && !props.isEmpty()) {
-                               Optional<GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
-                               if (isBasePropOp.isPresent()) {
-                                       GroupProperty propIsBase = isBasePropOp.get();
-                                       isBase = Boolean.parseBoolean(propIsBase.getValue());
-
-                               } else {
-                                       BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
-                                       // return
-                                       // Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-
-                               }
-                       }
-
-                       List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
-                       List<ArtifactDefinition> artifactsFromComponent = new ArrayList<>();
-                       List<String> artifactsIds = group.getArtifacts();
-
-                       Map<String, ArtifactDefinition> deploymentArtifacts = null;
-                       if (MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
-                               deploymentArtifacts = component.getDeploymentArtifacts().values().stream().collect(Collectors.toMap(a -> a.getUniqueId(), a -> a));
-                       }
-
-                       if (artifactsIds != null && !artifactsIds.isEmpty()) {
-                               for (String id : artifactsIds) {
-                                       if (MapUtils.isEmpty(deploymentArtifacts) || !deploymentArtifacts.containsKey(id)) {
-                                               log.debug("Failed to get artifact {} . Status is {} ", id, StorageOperationStatus.NOT_FOUND);
-                                               ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND));
-                                               result = Either.right(responseFormat);
-                                               return result;
-                                       }
-                                       artifactsFromComponent.add(deploymentArtifacts.get(id));
-                               }
-                               if (!artifactsFromComponent.isEmpty()) {
-                                       for (ArtifactDefinition artifactDefinition : artifactsFromComponent) {
-                                               ArtifactDefinitionInfo artifactDefinitionInfo = new ArtifactDefinitionInfo(artifactDefinition);
-                                               artifacts.add(artifactDefinitionInfo);
-                                       }
-                               }
-
-                       }
-                       GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
-                       resultInfo.setIsBase(isBase);
-                       if (!artifacts.isEmpty())
-                               resultInfo.setArtifacts(artifacts);
-
-                       result = Either.left(resultInfo);
-
-                       return result;
-
-               } finally {
-
-                       if (false == inTransaction) {
-
-                               if (result == null || result.isRight()) {
-                                       log.debug("Going to execute rollback on create group.");
-                                       titanDao.rollback();
-                               } else {
-                                       log.debug("Going to execute commit on create group.");
-                                       titanDao.commit();
-                               }
-
-                       }
-
-               }
-
-       }
-
-       private Either<GroupDefinition, StorageOperationStatus> findGroupOnComponent(Component component, String groupId) {
-
-               Either<GroupDefinition, StorageOperationStatus> result = null;
-               if (CollectionUtils.isNotEmpty(component.getGroups())) {
-                       Optional<GroupDefinition> foundGroup = component.getGroups().stream().filter(g -> g.getUniqueId().equals(groupId)).findFirst();
-                       if (foundGroup.isPresent()) {
-                               result = Either.left(foundGroup.get());
-                       }
-               }
-               if (result == null) {
-                       result = Either.right(StorageOperationStatus.NOT_FOUND);
-               }
-               return result;
-       }
-
-       /**
-        * @param componentId
-        * @param userId
-        * @param componentType
-        * @param groups
-        * @param inTransaction
-        * @return
-        */
-       private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> validateGroupsBeforeUpdate(String componentId, String userId, ComponentTypeEnum componentType, List<GroupDefinition> groups, boolean inTransaction) {
-
-               Either<org.openecomp.sdc.be.model.Component, ResponseFormat> result;
-
-               // Validate user exist
-               Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, UPDATE_GROUP, inTransaction);
-               if (validateUserExists.isRight()) {
-                       result = Either.right(validateUserExists.right().value());
-                       return result;
-               }
-
-               // Validate component exist
-               String realComponentId = componentId;
-
-               ComponentParametersView componentParametersView = new ComponentParametersView();
-               componentParametersView.disableAll();
-               componentParametersView.setIgnoreGroups(false);
-               componentParametersView.setIgnoreArtifacts(false);
-               componentParametersView.setIgnoreUsers(false);
-               componentParametersView.setIgnoreComponentInstances(false);
-
-               Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
-
-               if (validateComponent.isRight()) {
-                       result = Either.right(validateComponent.right().value());
-                       return result;
-               }
-               org.openecomp.sdc.be.model.Component component = validateComponent.left().value();
-
-               // validate we can work on component
-               Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId);
-               if (canWork.isRight()) {
-                       result = Either.right(canWork.right().value());
-                       return result;
-               }
-
-               // Validate groups exists in the component
-               ResponseFormat validateGroupsInComponent = validateGroupsInComponentByFunc(groups, component, p -> p.getUniqueId());
-               if (validateGroupsInComponent != null) {
-                       result = Either.right(validateGroupsInComponent);
-                       return result;
-               }
-
-               Set<String> artifacts = new HashSet<>();
-               groups.forEach(p -> {
-                       if (p.getArtifacts() != null) {
-                               artifacts.addAll(p.getArtifacts());
-                       }
-               });
-               // validate all artifacts belongs to the component
-               Either<Boolean, ResponseFormat> verifyArtifactsBelongsToComponent = verifyArtifactsBelongsToComponent(component, new ArrayList<>(artifacts), UPDATE_GROUP);
-               if (verifyArtifactsBelongsToComponent.isRight()) {
-                       result = Either.right(verifyArtifactsBelongsToComponent.right().value());
-                       return result;
-               }
-
-               return Either.left(component);
-       }
-
-       /**
-        * @param groups
-        * @param component
-        * @param getByParam
-        *            - the method to fetch the key of the GroupDefinition(from groups) in order to compare to groups in the component
-        * @return
-        */
-       private ResponseFormat validateGroupsInComponentByFunc(List<GroupDefinition> groups, org.openecomp.sdc.be.model.Component component, Function<GroupDefinition, String> getByParam) {
-               ResponseFormat result = null;
-
-               List<GroupDefinition> currentGroups = component.getGroups();
-
-               boolean found = false;
-               List<String> updatedGroupsName = groups.stream().map(getByParam).collect(Collectors.toList());
-
-               List<String> missingGroupNames = updatedGroupsName;
-
-               if (currentGroups != null && false == currentGroups.isEmpty()) {
-                       List<String> currentGroupsName = currentGroups.stream().map(getByParam).collect(Collectors.toList());
-
-                       if (currentGroupsName.containsAll(updatedGroupsName)) {
-                               found = true;
-                       } else {
-                               currentGroupsName.removeAll(currentGroupsName);
-                               missingGroupNames = currentGroupsName;
-                       }
-               }
-               if (false == found) {
-                       String componentTypeForResponse = getComponentTypeForResponse(component);
-                       String listOfGroups = getAsString(missingGroupNames);
-                       result = componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, listOfGroups, component.getSystemName(), componentTypeForResponse);
-                       return result;
-               }
-
-               return null;
-       }
-
-       public String getAsString(List<String> list) {
-
-               if (list == null || list.isEmpty()) {
-                       return "";
-               }
-               StringBuilder builder = new StringBuilder();
-               list.forEach(p -> builder.append(p + ","));
-
-               String result = builder.toString();
-               return result.substring(0, result.length());
-
-       }
-
-       /**
-        * dissociate artifacts from a given group
-        * 
-        * @param componentId
-        * @param userId
-        * @param componentType
-        * @param groups
-        * @param shouldLockComp
-        * @param inTransaction
-        * @return
-        */
-       /*
-        * public Either<List<GroupDefinition>, ResponseFormat> dissociateArtifactsFromGroup(String componentId, String userId, ComponentTypeEnum componentType, List<GroupDefinition> groups, boolean shouldLockComp, boolean inTransaction) {
-        * 
-        * Either<List<GroupDefinition>, ResponseFormat> result = null;
-        * 
-        * if (shouldLockComp == true && inTransaction == true) { BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); // Cannot lock
-        * component since we are in a middle of another // transaction. ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; result = Either.right(componentsUtils.getResponseFormat(actionStatus)); return result; }
-        * 
-        * Component component = null;
-        * 
-        * try {
-        * 
-        * if (groups == null || groups.isEmpty()) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); }
-        * 
-        * Either<Component, ResponseFormat> validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); if (validateGroupsBeforeUpdate.isRight()) { result =
-        * Either.right(validateGroupsBeforeUpdate.right().value()); return result; }
-        * 
-        * component = validateGroupsBeforeUpdate.left().value();
-        * 
-        * if (shouldLockComp) { Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, "Group - Dissociate Artifacts"); if (lockComponent.isRight()) { return Either.right(lockComponent.right().value()); } }
-        * 
-        * List<GroupDefinition> updatedGroups = new ArrayList<>();
-        * 
-        * List<GroupDefinition> componentGroups = component.getGroups(); // per group, associate to it the artifacts for (GroupDefinition groupDefinition : groups) {
-        * 
-        * GroupDefinition componentGroup = componentGroups.stream().filter(p -> p.getUniqueId().equals(groupDefinition.getUniqueId())).findFirst().orElse(null); if (componentGroup != null) { List<String> componentArtifacts =
-        * componentGroup.getArtifacts(); int artifactsSizeInGroup = componentArtifacts == null ? 0 : componentArtifacts.size(); List<String> artifactsToDissociate = groupDefinition.getArtifacts();
-        * 
-        * // if no artifcats sent if (artifactsToDissociate == null || true == artifactsToDissociate.isEmpty()) { continue; }
-        * 
-        * if (artifactsSizeInGroup > 0) {
-        * 
-        * boolean containsAll = componentArtifacts.containsAll(artifactsToDissociate); if (false == containsAll) { // At least one artifact is // not associated to the // group log.debug("Some of the artifacts already dissociated to group {}" ,
-        * groupDefinition.getUniqueId()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_DISSOCIATED, componentGroup.getName())); } } else { if (artifactsSizeInGroup == 0) { if (artifactsToDissociate != null &&
-        * false == artifactsToDissociate.isEmpty()) { log.debug("No artifact is found under the group {}" , groupDefinition.getUniqueId()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_DISSOCIATED,
-        * componentGroup.getName())); } } } }
-        * 
-        * Either<GroupDefinition, StorageOperationStatus> associateArtifactsToGroup = groupOperation.dissociateArtifactsFromGroup(groupDefinition.getUniqueId(), groupDefinition.getArtifacts(), true);
-        * 
-        * if (associateArtifactsToGroup.isRight()) { ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateArtifactsToGroup.right().value()); result = Either.right(componentsUtils.getResponseFormat(actionStatus));
-        * log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); return result; } updatedGroups.add(associateArtifactsToGroup.left().value());
-        * 
-        * }
-        * 
-        * result = Either.left(updatedGroups); return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * } // unlock resource if (shouldLockComp && component != null) { graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); }
-        * 
-        * }
-        * 
-        * }
-        */
-
-       /*
-        * public Either<List<GroupDefinition>, ResponseFormat> createGroups(String componentId, String userId, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions, boolean shouldLockComp, boolean inTransaction) {
-        * 
-        * Either<List<GroupDefinition>, ResponseFormat> result = null;
-        * 
-        * List<GroupDefinition> groups = new ArrayList<>(); org.openecomp.sdc.be.model.Component component = null; try {
-        * 
-        * if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
-        * 
-        * if (shouldLockComp && inTransaction) { BeEcompErrorManager.getInstance().logInternalFlowError("createGroups", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); // Cannot lock component since we are in a middle of
-        * another // transaction. ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; result = Either.right(componentsUtils.getResponseFormat(actionStatus)); return result; }
-        * 
-        * Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, CREATE_GROUP, true); if (validateUserExists.isRight()) { result = Either.right(validateUserExists.right().value()); return result; }
-        * 
-        * User user = validateUserExists.left().value();
-        * 
-        * ComponentParametersView componentParametersView = new ComponentParametersView(); componentParametersView.disableAll(); componentParametersView.setIgnoreGroups(false); componentParametersView.setIgnoreArtifacts(false);
-        * componentParametersView.setIgnoreUsers(false); componentParametersView.setIgnoreComponentInstances(false);
-        * 
-        * Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, componentParametersView);
-        * 
-        * if (validateComponent.isRight()) { result = Either.right(validateComponent.right().value()); return result; } component = validateComponent.left().value();
-        * 
-        * if (shouldLockComp) { Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, "CreateGroups"); if (lockComponent.isRight()) { return Either.right(lockComponent.right().value()); } }
-        * 
-        * Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId); if (canWork.isRight()) { result = Either.right(canWork.right().value()); return result; }
-        * 
-        * for (GroupDefinition groupDefinition : groupDefinitions) { Either<GroupDefinition, ResponseFormat> createGroup = this.createGroup(component, user, componentType, groupDefinition, true); if (createGroup.isRight()) {
-        * log.debug("Failed to create group {}." , groupDefinition ); result = Either.right(createGroup.right().value()); return result; } GroupDefinition createdGroup = createGroup.left().value(); groups.add(createdGroup); } }
-        * 
-        * result = Either.left(groups); return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * } // unlock resource if (shouldLockComp && component != null) { graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); }
-        * 
-        * }
-        * 
-        * }
-        * 
-        * public Either<GroupDefinition, ResponseFormat> createGroup(Component component, User user, ComponentTypeEnum componentType, GroupDefinition groupDefinition, boolean inTransaction) {
-        * 
-        * Either<GroupDefinition, ResponseFormat> result = null;
-        * 
-        * log.trace("Going to create group {}" , groupDefinition);
-        * 
-        * try {
-        * 
-        * // 3. verify group not already exist List<GroupDefinition> groups = component.getGroups(); boolean found = false; if (groups != null && false == groups.isEmpty()) {
-        * 
-        * GroupDefinition existGroupDef = groups.stream().filter(p -> p.getName().equalsIgnoreCase(groupDefinition.getName())).findFirst().orElse(null);
-        * 
-        * found = existGroupDef != null; }
-        * 
-        * if (true == found) { String componentTypeForResponse = getComponentTypeForResponse(component); result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ALREADY_EXIST, groupDefinition.getName(), component.getNormalizedName(),
-        * componentTypeForResponse)); return result; }
-        * 
-        * // 4. verify type of group exist String groupType = groupDefinition.getType(); if (groupType == null || groupType.isEmpty()) { result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE,
-        * groupDefinition.getName())); return result; } Either<GroupTypeDefinition, StorageOperationStatus> getGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType, true); if (getGroupType.isRight()) { StorageOperationStatus status =
-        * getGroupType.right().value(); if (status == StorageOperationStatus.NOT_FOUND) { BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "group type " + groupType + " cannot be found", ErrorSeverity.INFO); result =
-        * Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, groupType)); return result; } else { result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); return result; } }
-        * 
-        * // 6. verify the component instances type are allowed according to // the member types in the group type GroupTypeDefinition groupTypeDefinition = getGroupType.left().value();
-        * 
-        * Either<Boolean, ResponseFormat> areValidMembers = verifyComponentInstancesAreValidMembers(component, componentType, groupDefinition.getName(), groupType, groupDefinition.getMembers(), groupTypeDefinition.getMembers());
-        * 
-        * if (areValidMembers.isRight()) { ResponseFormat responseFormat = areValidMembers.right().value(); result = Either.right(responseFormat); return result; }
-        * 
-        * // 7. verify the artifacts belongs to the component Either<Boolean, ResponseFormat> areValidArtifacts = verifyArtifactsBelongsToComponent(component, groupDefinition.getArtifacts(), CREATE_GROUP); if (areValidArtifacts.isRight()) {
-        * ResponseFormat responseFormat = areValidArtifacts.right().value(); result = Either.right(responseFormat); return result; }
-        * 
-        * NodeTypeEnum nodeTypeEnum = componentType.getNodeType();
-        * 
-        * // add invariantUUID String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); groupDefinition.setInvariantUUID(invariantUUID);
-        * 
-        * // add groupUUID String groupUUID = UniqueIdBuilder.generateUUID(); groupDefinition.setGroupUUID(groupUUID);
-        * 
-        * // add version groupDefinition.setVersion(INITIAL_VERSION);
-        * 
-        * // set groupType uid groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
-        * 
-        * Either<GroupDefinition, StorageOperationStatus> addGroupToGraph = groupOperation.addGroup(nodeTypeEnum, component.getUniqueId(), groupDefinition, true);
-        * 
-        * if (addGroupToGraph.isRight()) { StorageOperationStatus storageOperationStatus = addGroupToGraph.right().value(); ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus); result =
-        * Either.right(componentsUtils.getResponseFormat(actionStatus)); log.debug("Failed to create group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); } else { GroupDefinition
-        * groupDefinitionCreated = addGroupToGraph.left().value(); result = Either.left(groupDefinitionCreated); }
-        * 
-        * return result;
-        * 
-        * } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * }
-        * 
-        * }
-        * 
-        * public Either<List<GroupDefinition>, ResponseFormat> updateVfModuleGroupNames(String resourceSystemName, List<GroupDefinition> groups, boolean inTransaction) { List<GroupDefinition> updatedGroups = new ArrayList<>();
-        * Either<List<GroupDefinition>, ResponseFormat> updateGroupNamesRes = Either.left(updatedGroups); Either<GroupDefinition, StorageOperationStatus> updateGroupNameRes; Either<String, ResponseFormat> validateGenerateGroupNameRes; int counter; for
-        * (GroupDefinition group : groups) { if (!group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(group.getName()).matches()) { continue; } counter =
-        * Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]); validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), counter); if (validateGenerateGroupNameRes.isRight()) {
-        * updateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value()); break; } updateGroupNameRes = groupOperation.updateGroupName(group.getUniqueId(), validateGenerateGroupNameRes.left().value(), inTransaction); if
-        * (updateGroupNameRes.isRight()) { ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(updateGroupNameRes.right().value()); updateGroupNamesRes = Either.right(componentsUtils.getResponseFormat(actionStatus)); break; }
-        * updatedGroups.add(updateGroupNameRes.left().value()); } return updateGroupNamesRes; }
-        */
-
-       private Either<List<GroupProperty>, ResponseFormat> updateGroupPropertiesValue(String componentId, GroupDefinition currentGroup, List<GroupProperty> groupPropertyToUpdate, boolean inTransaction) {
-               Either<List<GroupProperty>, ResponseFormat> result;
-
-               Either<List<GroupProperty>, StorageOperationStatus> eitherUpdate = groupsOperation.updateGroupPropertiesOnComponent(componentId, currentGroup, groupPropertyToUpdate);
-               if (eitherUpdate.isRight()) {
-                       ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(eitherUpdate.right().value());
-                       result = Either.right(componentsUtils.getResponseFormat(actionStatus));
-               } else {
-                       result = Either.left(eitherUpdate.left().value());
-               }
-               return result;
-       }
-
-       public Either<Boolean, ResponseFormat> validateGenerateVfModuleGroupNames(List<ArtifactTemplateInfo> allGroups, String resourceSystemName, int startGroupCounter) {
-               Either<Boolean, ResponseFormat> validateGenerateGroupNamesRes = Either.left(true);
-               Collections.sort(allGroups, (art1, art2) -> ArtifactTemplateInfo.compareByGroupName(art1, art2));
-               for (ArtifactTemplateInfo group : allGroups) {
-                       Either<String, ResponseFormat> validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), startGroupCounter++);
-                       if (validateGenerateGroupNameRes.isRight()) {
-                               validateGenerateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value());
-                               break;
-                       }
-                       group.setGroupName(validateGenerateGroupNameRes.left().value());
-               }
-               return validateGenerateGroupNamesRes;
-       }
-
-       /**
-        * Generate module name from resourceName, description and counter
-        * 
-        * @param resourceSystemName
-        * @param description
-        * @param groupCounter
-        * @return
-        */
-       private Either<String, ResponseFormat> validateGenerateVfModuleGroupName(String resourceSystemName, String description, int groupCounter) {
-               Either<String, ResponseFormat> validateGenerateGroupNameRes;
-               if (resourceSystemName != null && description != null && Pattern.compile(Constants.MODULE_DESC_PATTERN).matcher(description).matches()) {
-                       final String fileName = description.replaceAll("\\.\\.", "\\.");
-                       validateGenerateGroupNameRes = Either.left(String.format(Constants.MODULE_NAME_FORMAT, resourceSystemName, FilenameUtils.removeExtension(fileName), groupCounter));
-               } else {
-                       validateGenerateGroupNameRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME));
-               }
-               return validateGenerateGroupNameRes;
-       }
-
-       public Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNames(Map<String, GroupDefinition> groups, String resourceSystemName) {
-
-               Map<String, GroupDefinition> updatedNamesGroups = new HashMap<>();
-               Either<Map<String, GroupDefinition>, ResponseFormat> result = Either.left(updatedNamesGroups);
-               for (Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
-                       GroupDefinition curGroup = groupEntry.getValue();
-                       String groupType = curGroup.getType();
-                       String groupName = groupEntry.getKey();
-                       int counter;
-                       String description;
-                       Either<String, ResponseFormat> newGroupNameRes;
-                       if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(groupName).matches()) {
-
-                               if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupEntry.getKey()).matches()) {
-                                       counter = Integer.parseInt(groupEntry.getKey().split(Constants.MODULE_NAME_DELIMITER)[1]);
-                                       description = curGroup.getDescription();
-                               } else {
-                                       counter = getNextVfModuleNameCounter(updatedNamesGroups);
-                                       description = groupName;
-                               }
-                               newGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, description, counter);
-                               if (newGroupNameRes.isRight()) {
-                                       log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
-                                       result = Either.right(newGroupNameRes.right().value());
-                                       break;
-                               }
-                               groupName = newGroupNameRes.left().value();
-                               curGroup.setName(groupName);
-                       }
-                       updatedNamesGroups.put(groupName, curGroup);
-               }
-               return result;
-       }
-
-       public int getNextVfModuleNameCounter(Map<String, GroupDefinition> groups) {
-               int counter = 0;
-               if (groups != null && !groups.isEmpty()) {
-                       counter = getNextVfModuleNameCounter(groups.values());
-               }
-               return counter;
-       }
-
-       public int getNextVfModuleNameCounter(Collection<GroupDefinition> groups) {
-               int counter = 0;
-               if (groups != null && !groups.isEmpty()) {
-                       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())
-                                       .map(group -> Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1])).collect(Collectors.toList());
-                       counter = (counters == null || counters.isEmpty()) ? 0 : counters.stream().max((a, b) -> Integer.compare(a, b)).get() + 1;
-               }
-               return counter;
-       }
-
-       public Either<List<GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesOnGraph(List<GroupDefinition> groups, Component component, boolean inTransaction) {
-               List<GroupDefinition> updatedGroups = new ArrayList<>();
-               Either<List<GroupDefinition>, ResponseFormat> result = Either.left(updatedGroups);
-
-               for (GroupDefinition group : groups) {
-                       String groupType = group.getType();
-                       String oldGroupName = group.getName();
-                       String newGroupName;
-                       Either<String, ResponseFormat> newGroupNameRes;
-                       Either<GroupDefinition, StorageOperationStatus> updateGroupNameRes;
-                       int counter;
-                       if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(oldGroupName).matches()) {
-                               counter = Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]);
-                               newGroupNameRes = validateGenerateVfModuleGroupName(component.getSystemName(), group.getDescription(), counter);
-                               if (newGroupNameRes.isRight()) {
-                                       log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
-                                       result = Either.right(newGroupNameRes.right().value());
-                                       break;
-                               }
-                               newGroupName = newGroupNameRes.left().value();
-                               group.setName(newGroupName);
-
-                       }
-                       updatedGroups.add(group);
-
-               }
-
-               result = Either.left(updatedGroups);
-               return result;
-       }
-
-       /*
-        * public Either<List<GroupDefinition>, ResponseFormat> createGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions, boolean inTransaction) {
-        * 
-        * List<GroupDefinition> generatedGroups = new ArrayList<>(); Either<List<GroupDefinition>, ResponseFormat> result = Either.left(generatedGroups);
-        * 
-        * try {
-        * 
-        * if (groupDefinitions != null && false == groupDefinitions.isEmpty()) { for (GroupDefinition groupDefinition : groupDefinitions) { Either<GroupDefinition, ResponseFormat> createGroup = this.createGroup(component, user, componentType,
-        * groupDefinition, true); if (createGroup.isRight()) { result = Either.right(createGroup.right().value()); return result; } GroupDefinition generatedGroup = createGroup.left().value(); generatedGroups.add(generatedGroup); } }
-        * 
-        * return result; } finally {
-        * 
-        * if (false == inTransaction) {
-        * 
-        * if (result == null || result.isRight()) { log.debug("Going to execute rollback on create group."); titanDao.rollback(); } else { log.debug("Going to execute commit on create group."); titanDao.commit(); }
-        * 
-        * }
-        * 
-        * }
-        * 
-        * }
-        */
-
-       public Either<GroupDefinitionInfo, ResponseFormat> getGroupInstWithArtifactsById(ComponentTypeEnum componentType, String componentId, String componentInstanceId, String groupInstId, String userId, boolean inTransaction) {
-               Either<GroupDefinitionInfo, ResponseFormat> result = null;
-
-               // Validate user exist
-               Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, UPDATE_GROUP, true);
-
-               if (validateUserExists.isRight()) {
-                       result = Either.right(validateUserExists.right().value());
-                       return result;
-               }
-
-               // Validate component exist
-               org.openecomp.sdc.be.model.Component component = null;
-               String realComponentId = componentId;
-
-               try {
-                       ComponentParametersView componentParametersView = new ComponentParametersView();
-                       componentParametersView.disableAll();
-                       componentParametersView.setIgnoreUsers(false);
-                       componentParametersView.setIgnoreComponentInstances(false);
-                       componentParametersView.setIgnoreArtifacts(false);
-
-                       Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
-                       if (validateComponent.isRight()) {
-                               result = Either.right(validateComponent.right().value());
-                               return result;
-                       }
-                       component = validateComponent.left().value();
-                       Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceRes = findComponentInstanceAndGroupInstanceOnComponent(component, componentInstanceId, groupInstId);
-
-                       if (findComponentInstanceAndGroupInstanceRes.isRight()) {
-                               log.debug("Failed to get group {} . Status is {} ", groupInstId, findComponentInstanceAndGroupInstanceRes.right().value());
-                               ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findComponentInstanceAndGroupInstanceRes.right().value()));
-                               result = Either.right(responseFormat);
-                               return result;
-                       }
-
-                       GroupInstance group = findComponentInstanceAndGroupInstanceRes.left().value().getRight();
-                       ComponentInstance componentInstance = findComponentInstanceAndGroupInstanceRes.left().value().getLeft();
-
-                       Boolean isBase = null;// Constants.IS_BASE;
-                       List<? extends GroupProperty> props = group.convertToGroupInstancesProperties();
-                       if (props != null && !props.isEmpty()) {
-                               Optional<? extends GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
-                               if (isBasePropOp.isPresent()) {
-                                       GroupProperty propIsBase = isBasePropOp.get();
-                                       isBase = Boolean.parseBoolean(propIsBase.getValue());
-
-                               } else {
-                                       BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
-                                       // return
-                                       // Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-
-                               }
-                       }
-
-                       List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
-                       List<String> artifactsIds = group.getArtifacts();
-                       if (artifactsIds != null && !artifactsIds.isEmpty()) {
-
-                               List<ComponentInstance> instances = component.getComponentInstances();
-                               if (instances != null) {
-                                       Optional<ComponentInstance> findFirst = instances.stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst();
-                                       if (findFirst.isPresent()) {
-                                               ComponentInstance ci = findFirst.get();
-                                               Map<String, ArtifactDefinition> deploymentArtifacts = ci.getDeploymentArtifacts();
-                                               for (String id : artifactsIds) {
-                                                       Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
-                                                       if (artOp.isPresent()) {
-                                                               artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
-                                                       }
-                                               }
-                                               List<String> instArtifactsIds = group.getGroupInstanceArtifacts();
-                                               for (String id : instArtifactsIds) {
-                                                       Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
-                                                       if (artOp.isPresent()) {
-                                                               artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
-                                                       }
-                                               }
-                                       }
-
-                               }
-                       }
-                       GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
-                       resultInfo.setIsBase(isBase);
-                       if (!artifacts.isEmpty())
-                               resultInfo.setArtifacts(artifacts);
-
-                       result = Either.left(resultInfo);
-
-                       return result;
-
-               } finally {
-
-                       if (false == inTransaction) {
-
-                               if (result == null || result.isRight()) {
-                                       log.debug("Going to execute rollback on create group.");
-                                       titanDao.rollback();
-                               } else {
-                                       log.debug("Going to execute commit on create group.");
-                                       titanDao.commit();
-                               }
-
-                       }
-
-               }
-       }
-
-       private Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceOnComponent(Component component, String componentInstanceId, String groupInstId) {
-
-               Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> result = null;
-               if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
-                       Optional<GroupInstance> foundGroup;
-                       Optional<ComponentInstance> foundComponent = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst();
-                       if (foundComponent.isPresent() && CollectionUtils.isNotEmpty(foundComponent.get().getGroupInstances())) {
-                               foundGroup = foundComponent.get().getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstId)).findFirst();
-                               if (foundGroup.isPresent()) {
-                                       result = Either.left(new ImmutablePair<>(foundComponent.get(), foundGroup.get()));
-                               }
-                       }
-               }
-               if (result == null) {
-                       result = Either.right(StorageOperationStatus.NOT_FOUND);
-               }
-               return result;
-       }
-
-       private int getLatestIntProperty(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues, PropertyNames propertyKey) {
-               String value;
-               if (newValues.containsKey(propertyKey)) {
-                       value = newValues.get(propertyKey);
-               } else {
-                       value = parentValues.get(propertyKey);
-               }
-               return Integer.valueOf(value);
-       }
-
-       private boolean isPropertyChanged(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues, final PropertyNames minInstances) {
-               return newValues.containsKey(minInstances) && newValues.containsKey(minInstances) && !newValues.get(minInstances).equals(parentValues.get(minInstances));
-       }
-
-       private Either<Boolean, ResponseFormat> validateMinMaxAndInitialCountPropertyLogicVF(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues) {
-
-               int latestMaxInstances = getLatestIntProperty(newValues, parentValues, PropertyNames.MAX_INSTANCES);
-               int latestInitialCount = getLatestIntProperty(newValues, parentValues, PropertyNames.INITIAL_COUNT);
-               int latestMinInstances = getLatestIntProperty(newValues, parentValues, PropertyNames.MIN_INSTANCES);
-               Either<Boolean, ResponseFormat> result = Either.left(true);
-
-               if (isPropertyChanged(newValues, parentValues, PropertyNames.INITIAL_COUNT) && result.isLeft()) {
-                       if (latestInitialCount > latestMaxInstances || latestInitialCount < latestMinInstances) {
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_INITIAL_COUNT_PROPERTY_VALUE, PropertyNames.INITIAL_COUNT.getPropertyName(), String.valueOf(latestMinInstances), String.valueOf(latestMaxInstances)));
-                       }
-               }
-               if (isPropertyChanged(newValues, parentValues, PropertyNames.MAX_INSTANCES) && result.isLeft()) {
-                       if (latestMaxInstances < latestInitialCount) {
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_PROPERTY_VALUE_LOWER_HIGHER, PropertyNames.MAX_INSTANCES.getPropertyName(), "higher", String.valueOf(latestInitialCount)));
-                       }
-
-               }
-               if (isPropertyChanged(newValues, parentValues, PropertyNames.MIN_INSTANCES) && result.isLeft()) {
-                       if (latestMinInstances > latestInitialCount) {
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_PROPERTY_VALUE_LOWER_HIGHER, PropertyNames.MIN_INSTANCES.getPropertyName(), "lower", String.valueOf(latestInitialCount)));
-                       }
-
-               }
-               return result;
-       }
-
-       private Either<Boolean, ResponseFormat> validateMinMaxAndInitialCountPropertyLogic(Map<PropertyNames, String> newValues, Map<PropertyNames, String> currValues, Map<PropertyNames, String> parentValues) {
-
-               Either<Boolean, ResponseFormat> result;
-               for (Entry<PropertyNames, String> entry : newValues.entrySet()) {
-                       PropertyNames currPropertyName = entry.getKey();
-                       if (currPropertyName == PropertyNames.MIN_INSTANCES) {
-                               String minValue = parentValues.get(PropertyNames.MIN_INSTANCES);
-                               String maxValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
-                               result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
-                                               new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
-                               if (result.isRight()) {
-                                       return result;
-                               }
-                       } else if (currPropertyName == PropertyNames.INITIAL_COUNT) {
-                               String minValue = newValues.containsKey(PropertyNames.MIN_INSTANCES) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.MIN_INSTANCES);
-                               String maxValue = newValues.containsKey(PropertyNames.MAX_INSTANCES) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.MAX_INSTANCES);
-                               result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
-                                               new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
-                               if (result.isRight()) {
-                                       return result;
-                               }
-                       } else if (currPropertyName == PropertyNames.MAX_INSTANCES) {
-                               String minValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
-                               String maxValue = parentValues.get(PropertyNames.MAX_INSTANCES);
-                               result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
-                                               new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
-                               if (result.isRight()) {
-                                       return result;
-                               }
-                       }
-               }
-               return Either.left(true);
-       }
-
-       private Either<Boolean, ResponseFormat> validateValueInRange(ImmutablePair<PropertyNames, String> newValue, ImmutablePair<PropertyNames, String> min, ImmutablePair<PropertyNames, String> max) {
-               Either<Boolean, ResponseFormat> result;
-               final String warnMessage = "Failed to validate {} as property value of {}. It must be not higher than {}, and not lower than {}.";
-               int newValueInt = parseIntValue(newValue.getValue(), newValue.getKey());
-               int minInt = parseIntValue(min.getValue(), min.getKey());
-               int maxInt = parseIntValue(max.getValue(), max.getKey());
-               if (newValueInt < 0 || minInt < 0 || maxInt < 0) {
-                       result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY));
-               } else if (newValueInt < minInt || newValueInt > maxInt) {
-                       log.debug(warnMessage, newValue.getValue(), newValue.getKey().getPropertyName(), min.getValue(), max.getValue());
-                       result = Either
-                                       .right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_MIN_MAX_INSTANCES_PROPERTY_VALUE, newValue.getKey().getPropertyName(), maxInt == Integer.MAX_VALUE ? Constants.UNBOUNDED : max.getValue(), min.getValue()));
-               } else {
-                       result = Either.left(true);
-               }
-               return result;
-       }
-
-       private int parseIntValue(String value, PropertyNames propertyName) {
-               int result;
-               if (propertyName == PropertyNames.MAX_INSTANCES) {
-                       result = convertIfUnboundMax(value);
-               } else if (NumberUtils.isNumber(value)) {
-                       result = Integer.parseInt(value);
-               } else {
-                       result = -1;
-               }
-               return result;
-       }
-
-       /**
-        * validates received new property values and updates group instance in case of success
-        * 
-        * @param oldGroupInstance
-        * @param groupInstanceId
-        * @param newProperties
-        * @param inTransaction
-        * @return
-        */
-       public Either<GroupInstance, ResponseFormat> validateAndUpdateGroupInstancePropertyValues(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties, boolean inTransaction) {
-
-               Either<GroupInstance, ResponseFormat> actionResult = null;
-               Either<GroupInstance, StorageOperationStatus> updateGroupInstanceResult = null;
-               Either<List<GroupInstanceProperty>, ResponseFormat> validateRes = validateReduceGroupInstancePropertiesBeforeUpdate(oldGroupInstance, newProperties);
-               if (validateRes.isRight()) {
-                       log.debug("Failed to validate group instance {} properties before update. ", oldGroupInstance.getName());
-                       actionResult = Either.right(validateRes.right().value());
-               }
-               if (actionResult == null) {
-                       List<GroupInstanceProperty> validatedReducedNewProperties = validateRes.left().value();
-                       updateGroupInstanceResult = groupsOperation.updateGroupInstancePropertyValuesOnGraph(componentId, instanceId, oldGroupInstance, validatedReducedNewProperties);
-                       if (updateGroupInstanceResult.isRight()) {
-                               log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
-                               actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateGroupInstanceResult.right().value())));
-                       }
-               }
-               if (actionResult == null) {
-                       actionResult = Either.left(updateGroupInstanceResult.left().value());
-               }
-               return actionResult;
-       }
-
-       private Either<List<GroupInstanceProperty>, ResponseFormat> validateReduceGroupInstancePropertiesBeforeUpdate(GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
-
-               Either<Boolean, ResponseFormat> validationRes = null;
-               Either<List<GroupInstanceProperty>, ResponseFormat> actionResult;
-               Map<String, GroupInstanceProperty> existingProperties = oldGroupInstance.convertToGroupInstancesProperties().stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
-               Map<PropertyNames, String> newPropertyValues = new EnumMap<>(PropertyNames.class);
-               List<GroupInstanceProperty> reducedProperties = new ArrayList<>();
-               String currPropertyName;
-               try {
-                       for (GroupInstanceProperty currNewProperty : newProperties) {
-                               currPropertyName = currNewProperty.getName();
-                               validationRes = handleAndAddProperty(reducedProperties, newPropertyValues, currNewProperty, existingProperties.get(currPropertyName));
-                               if (validationRes.isRight()) {
-                                       log.debug("Failed to handle property {} of group instance {}. ", currPropertyName, oldGroupInstance.getName());
-                                       break;
-                               }
-                       }
-                       if (validationRes == null || validationRes.isLeft()) {
-                               Map<PropertyNames, String> existingPropertyValues = new EnumMap<>(PropertyNames.class);
-                               Map<PropertyNames, String> parentPropertyValues = new EnumMap<>(PropertyNames.class);
-                               fillValuesAndParentValuesFromExistingProperties(existingProperties, existingPropertyValues, parentPropertyValues);
-                               validationRes = validateMinMaxAndInitialCountPropertyLogic(newPropertyValues, existingPropertyValues, parentPropertyValues);
-                       }
-                       if (validationRes.isLeft()) {
-                               actionResult = Either.left(reducedProperties);
-                       } else {
-                               actionResult = Either.right(validationRes.right().value());
-                       }
-               } catch (Exception e) {
-                       log.error("Exception occured during validation and reducing group instance properties. The message is {}", e.getMessage(), e);
-                       actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-               }
-               return actionResult;
-       }
-
-       private void fillValuesAndParentValuesFromExistingProperties(Map<String, GroupInstanceProperty> existingProperties, Map<PropertyNames, String> propertyValues, Map<PropertyNames, String> parentPropertyValues) {
-               PropertyNames[] allPropertyNames = PropertyNames.values();
-               for (PropertyNames name : allPropertyNames) {
-                       if (isUpdatable(name)) {
-                               propertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getValue()));
-                               parentPropertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getParentValue()));
-                       }
-               }
-       }
-
-       private Either<Boolean, ResponseFormat> handleAndAddProperty(List<GroupInstanceProperty> reducedProperties, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty currNewProperty, GroupInstanceProperty currExistingProperty) {
-
-               Either<Boolean, ResponseFormat> validationRes = null;
-               String currPropertyName = currNewProperty.getName();
-               PropertyNames propertyName = PropertyNames.findName(currPropertyName);
-               try {
-                       if (currExistingProperty == null) {
-                               log.warn("The value of property with the name {} cannot be updated. The property not found on group instance. ", currPropertyName);
-                       } else if (isUpdatable(propertyName)) {
-                               validationRes = validateAndUpdatePropertyValue(currNewProperty, currExistingProperty);
-                               if (validationRes.isRight()) {
-                                       log.debug("Failed to validate property value {} of property {}. ", currNewProperty.getValue(), currPropertyName);
-                               } else {
-                                       addPropertyUpdatedValues(reducedProperties, propertyName, newPropertyValues, currNewProperty, currExistingProperty);
-                               }
-                       } else {
-                               validateImmutableProperty(currExistingProperty, currNewProperty);
-                       }
-                       if (validationRes == null) {
-                               validationRes = Either.left(true);
-                       }
-               } catch (Exception e) {
-                       log.error("Exception occured during handle and adding property. The message is {}", e.getMessage(), e);
-                       validationRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-               }
-               return validationRes;
-       }
-
-       private boolean isUpdatable(PropertyNames updatablePropertyName) {
-               return updatablePropertyName != null && updatablePropertyName.getUpdateBehavior().getLevelNumber() >= GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL.getLevelNumber();
-       }
-
-       private void addPropertyUpdatedValues(List<GroupInstanceProperty> reducedProperties, PropertyNames propertyName, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
-
-               String newValue = newProperty.getValue();
-               if (!newValue.equals(String.valueOf(existingProperty.getValue()))) {
-                       newProperty.setValueUniqueUid(existingProperty.getValueUniqueUid());
-                       reducedProperties.add(newProperty);
-               }
-               if (!isEmptyMinInitialCountValue(propertyName, newValue)) {
-                       newPropertyValues.put(propertyName, newValue);
-               }
-       }
-
-       private boolean isEmptyMinInitialCountValue(PropertyNames propertyName, String newValue) {
-               boolean result = false;
-               if ((propertyName == PropertyNames.MIN_INSTANCES || propertyName == PropertyNames.INITIAL_COUNT) && !NumberUtils.isNumber(newValue)) {
-                       result = true;
-               }
-               return result;
-       }
-
-       private int convertIfUnboundMax(String value) {
-
-               int result;
-               if (!NumberUtils.isNumber(value)) {
-                       result = Integer.MAX_VALUE;
-               } else {
-                       result = Integer.parseInt(value);
-               }
-               return result;
-       }
-
-       private Either<Boolean, ResponseFormat> validateAndUpdatePropertyValue(GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
-
-               Either<Boolean, ResponseFormat> validationRes = null;
-               String parentValue = existingProperty.getParentValue();
-
-               newProperty.setParentValue(parentValue);
-               if (StringUtils.isEmpty(newProperty.getValue())) {
-                       newProperty.setValue(parentValue);
-               }
-               if (StringUtils.isEmpty(existingProperty.getValue())) {
-                       existingProperty.setValue(parentValue);
-               }
-               StorageOperationStatus status = groupOperation.validateAndUpdatePropertyValue(newProperty);
-               if (status != StorageOperationStatus.OK) {
-                       log.debug("Failed to validate property value {} of property with name {}. Status is {}. ", newProperty.getValue(), newProperty.getName(), status);
-                       validationRes = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
-               }
-               if (validationRes == null) {
-                       validationRes = Either.left(true);
-               }
-               return validationRes;
-       }
-
-       private void validateImmutableProperty(GroupProperty oldProperty, GroupProperty newProperty) {
-               if (oldProperty.getValue() == null && newProperty.getValue() != null || oldProperty.getValue() != null && !oldProperty.getValue().equals(newProperty.getValue())) {
-                       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());
-               }
-       }
-
-       public Either<List<GroupDefinition>, ResponseFormat> createGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions) {
-
-               Map<String, GroupDataDefinition> groups = new HashMap<>();
-               // Map<String, MapPropertiesDataDefinition> groupsPropertiesMap = new HashMap<>();
-               Either<List<GroupDefinition>, ResponseFormat> result = null;
-               Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
-               Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-               if (allDataTypes.isRight()) {
-                       TitanOperationStatus status = allDataTypes.right().value();
-                       BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
-                       return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
-
-               }
-
-               // handle groups and convert to tosca data
-               if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
-                       for (GroupDefinition groupDefinition : groupDefinitions) {
-                               Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, user, componentType, groupDefinition, allDataTypes.left().value());
-                               if (handleGroupRes.isRight()) {
-                                       result = Either.right(handleGroupRes.right().value());
-                                       break;
-                               }
-                               GroupDefinition handledGroup = handleGroupRes.left().value();
-                               groups.put(handledGroup.getName(), new GroupDataDefinition(handledGroup));
-
-                       }
-               }
-               if (result == null) {
-                       createGroupsResult = groupsOperation.createGroups(component, user, componentType, groups);
-                       if (createGroupsResult.isRight()) {
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
-                       }
-               }
-               if (result == null) {
-                       result = Either.left(createGroupsResult.left().value());
-               }
-               return result;
-       }
-
-       public Either<List<GroupDefinition>, ResponseFormat> addGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions) {
-
-               Either<List<GroupDefinition>, ResponseFormat> result = null;
-               Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
-               List<GroupDataDefinition> groups = new ArrayList<>();
-
-               Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
-               if (allDataTypes.isRight()) {
-                       TitanOperationStatus status = allDataTypes.right().value();
-                       BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
-                       return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
-
-               }
-
-               // handle groups and convert to tosca data
-               if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
-                       for (GroupDefinition groupDefinition : groupDefinitions) {
-                               Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, user, componentType, groupDefinition, allDataTypes.left().value());
-                               if (handleGroupRes.isRight()) {
-                                       result = Either.right(handleGroupRes.right().value());
-                                       break;
-                               }
-                               GroupDefinition handledGroup = handleGroupRes.left().value();
-                               groups.add(new GroupDataDefinition(handledGroup));
-                       }
-               }
-               if (result == null) {
-                       createGroupsResult = groupsOperation.addGroups(component, user, componentType, groups);
-                       if (createGroupsResult.isRight()) {
-                               result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
-                       }
-               }
-               if (result == null) {
-                       result = Either.left(createGroupsResult.left().value());
-               }
-               return result;
-       }
-
-       public Either<List<GroupDefinition>, ResponseFormat> deleteGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions) {
-
-               Either<List<GroupDefinition>, ResponseFormat> result = null;
-               Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
-
-               createGroupsResult = groupsOperation.deleteGroups(component, user, componentType, groupDefinitions.stream().map(x -> new GroupDataDefinition(x)).collect(Collectors.toList()));
-               if (createGroupsResult.isRight()) {
-                       result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
-               }
-
-               if (result == null) {
-                       result = Either.left(createGroupsResult.left().value());
-               }
-               return result;
-       }
-
-       /**
-        * Update specific group version
-        * 
-        * @param groupDefinition
-        * @param inTransaction
-        * @return
-        */
-       public Either<List<GroupDefinition>, ResponseFormat> updateGroups(Component component, ComponentTypeEnum componentType, List<GroupDefinition> groupDefinitions) {
-
-               Either<List<GroupDefinition>, ResponseFormat> result = null;
-               Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
-
-               createGroupsResult = groupsOperation.updateGroups(component, componentType, groupDefinitions.stream().map(x -> new GroupDataDefinition(x)).collect(Collectors.toList()));
-               if (createGroupsResult.isRight()) {
-                       result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
-               }
-
-               if (result == null) {
-                       result = Either.left(createGroupsResult.left().value());
-               }
-               return result;
-       }
-
-       public Either<GroupDefinition, ResponseFormat> handleGroup(Component component, User user, ComponentTypeEnum componentType, GroupDefinition groupDefinition, Map<String, DataTypeDefinition> allDAtaTypes) {
-
-               Either<GroupDefinition, ResponseFormat> result = null;
-
-               log.trace("Going to create group {}", groupDefinition);
-               // 3. verify group not already exist
-               List<GroupDefinition> groups = component.getGroups();
-               boolean found = false;
-               if (groups != null && false == groups.isEmpty()) {
-
-                       GroupDefinition existGroupDef = groups.stream().filter(p -> p.getName().equalsIgnoreCase(groupDefinition.getName())).findFirst().orElse(null);
-
-                       found = existGroupDef != null;
-               }
-               if (true == found) {
-                       String componentTypeForResponse = getComponentTypeForResponse(component);
-                       result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ALREADY_EXIST, groupDefinition.getName(), component.getNormalizedName(), componentTypeForResponse));
-                       return result;
-               }
-               // 4. verify type of group exist
-               String groupType = groupDefinition.getType();
-               if (groupType == null || groupType.isEmpty()) {
-                       result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupDefinition.getName()));
-                       return result;
-               }
-               Either<GroupTypeDefinition, StorageOperationStatus> getGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType, true);
-               if (getGroupType.isRight()) {
-                       StorageOperationStatus status = getGroupType.right().value();
-                       if (status == StorageOperationStatus.NOT_FOUND) {
-                               BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "group type " + groupType + " cannot be found", ErrorSeverity.INFO);
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, groupType));
-                               return result;
-                       } else {
-                               result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
-                               return result;
-                       }
-               }
-               // 6. verify the component instances type are allowed according to
-               // the member types in the group type
-               GroupTypeDefinition groupTypeDefinition = getGroupType.left().value();
-
-               Either<Boolean, ResponseFormat> areValidMembers = verifyComponentInstancesAreValidMembers(component, componentType, groupDefinition.getName(), groupType, groupDefinition.getMembers(), groupTypeDefinition.getMembers());
-
-               if (areValidMembers.isRight()) {
-                       ResponseFormat responseFormat = areValidMembers.right().value();
-                       result = Either.right(responseFormat);
-                       return result;
-               }
-               // 7. verify the artifacts belongs to the component
-               Either<Boolean, ResponseFormat> areValidArtifacts = verifyArtifactsBelongsToComponent(component, groupDefinition.getArtifacts(), CREATE_GROUP);
-               if (areValidArtifacts.isRight()) {
-                       ResponseFormat responseFormat = areValidArtifacts.right().value();
-                       result = Either.right(responseFormat);
-                       return result;
-               }
-               List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
-
-               List<GroupProperty> properties = groupDefinition.convertToGroupProperties();
-               List<GroupProperty> updatedGroupTypeProperties = new ArrayList<>();
-               if (properties != null && false == properties.isEmpty()) {
-
-                       if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) {
-                               BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "group type does not have properties", ErrorSeverity.INFO);
-                               return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.MATCH_NOT_FOUND))));
-                       }
-
-                       Map<String, PropertyDefinition> groupTypePropertiesMap = groupTypeProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
-
-                       Either<GroupProperty, TitanOperationStatus> addPropertyResult = null;
-                       int i = 1;
-                       for (GroupProperty prop : properties) {
-                               addPropertyResult = handleProperty(prop, groupTypePropertiesMap.get(prop.getName()), i, allDAtaTypes);
-                               if (addPropertyResult.isRight()) {
-                                       BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "failed to validate property", ErrorSeverity.INFO);
-                                       return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyResult.right().value()))));
-                               }
-                               updatedGroupTypeProperties.add(addPropertyResult.left().value());
-
-                               i++;
-                       }
-               }
-               if (groupDefinition.getUniqueId() == null) {
-                       String uid = UniqueIdBuilder.buildGroupingUid(component.getUniqueId(), groupDefinition.getName());
-                       groupDefinition.setUniqueId(uid);
-               }
-               groupDefinition.convertFromGroupProperties(updatedGroupTypeProperties);
-               groupDefinition.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
-               groupDefinition.setGroupUUID(UniqueIdBuilder.generateUUID());
-               groupDefinition.setVersion(INITIAL_VERSION);
-               groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
-
-               return Either.left(groupDefinition);
-       }
-
-       public Either<GroupProperty, TitanOperationStatus> handleProperty(GroupProperty groupProperty, PropertyDefinition prop, Integer index, Map<String, DataTypeDefinition> allDataTypes) {
-
-               if (prop == null) {
-                       return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-               }
-
-               PropertyDataDefinition propDataDef = prop;
-               String propertyType = propDataDef.getType();
-               String value = groupProperty.getValue();
-
-               Either<String, TitanOperationStatus> checkInnerType = propertyOperation.checkInnerType(propDataDef);
-               if (checkInnerType.isRight()) {
-                       TitanOperationStatus status = checkInnerType.right().value();
-                       return Either.right(status);
-               }
-
-               String innerType = checkInnerType.left().value();
-
-               log.debug("Before validateAndUpdatePropertyValue");
-               Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes);
-               log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
-
-               String newValue = value;
-               if (isValid.isRight()) {
-                       Boolean res = isValid.right().value();
-                       if (res == false) {
-                               return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
-                       }
-               } else {
-                       Object object = isValid.left().value();
-                       if (object != null) {
-                               newValue = object.toString();
-                       }
-               }
-
-               String uniqueId = UniqueIdBuilder.buildGroupPropertyValueUid((String) prop.getUniqueId(), index);
-
-               groupProperty.setUniqueId(uniqueId);
-               groupProperty.setValue(newValue);
-               groupProperty.setType(prop.getType());
-               groupProperty.setDefaultValue(prop.getDefaultValue());
-               groupProperty.setDescription(prop.getDescription());
-               groupProperty.setSchema(prop.getSchema());
-               groupProperty.setPassword(prop.isPassword());
-               groupProperty.setParentUniqueId(prop.getUniqueId());
-
-               log.debug("Before adding property value to graph {}", groupProperty);
-
-               return Either.left(groupProperty);
-       }
+    public static final String GROUP_DELIMITER_REGEX = "\\.\\.";
+    private static String ADDING_GROUP = "AddingGroup";
+
+    public static final String INITIAL_VERSION = "1";
+
+    private static final String CREATE_GROUP = "CreateGroup";
+
+    private static final String UPDATE_GROUP = "UpdateGroup";
+
+    private static final String GET_GROUP = "GetGroup";
+
+    private static final String DELETE_GROUP = "GetGroup";
+
+    private static final Logger log = LoggerFactory.getLogger(GroupBusinessLogic.class);
+
+    @javax.annotation.Resource
+    private AccessValidations accessValidations;
+
+    @javax.annotation.Resource
+    private GroupTypeOperation groupTypeOperation;
+
+    @Autowired
+    private ArtifactsOperations artifactsOperation;
+
+    @Autowired
+    private GroupsOperation groupsOperation;
+    @Autowired
+    private ApplicationDataTypeCache dataTypeCache;
+
+    private String getComponentTypeForResponse(org.openecomp.sdc.be.model.Component component) {
+        String componentTypeForResponse = "SERVICE";
+        if (component instanceof Resource) {
+            componentTypeForResponse = ((Resource) component).getResourceType().name();
+        }
+        return componentTypeForResponse;
+    }
+
+    /**
+     * Verify that the artifact members belongs to the component
+     *
+     * @param component
+     * @param artifacts
+     * @return
+     */
+    private Either<Boolean, ResponseFormat> verifyArtifactsBelongsToComponent(Component component, List<String> artifacts, String context) {
+
+        if (CollectionUtils.isEmpty(artifacts)) {
+            return Either.left(true);
+        }
+
+        Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
+        if (MapUtils.isEmpty(deploymentArtifacts)) {
+            BeEcompErrorManager.getInstance().logInvalidInputError(context, "No deployment artifact found under component " + component.getNormalizedName(), ErrorSeverity.INFO);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+        }
+
+        List<String> currentArtifacts = deploymentArtifacts.values().stream().map(p -> p.getUniqueId()).collect(toList());
+        log.debug("The deployment artifacts of component {} are {}", component.getNormalizedName(), deploymentArtifacts);
+        if (!currentArtifacts.containsAll(artifacts)) {
+            BeEcompErrorManager.getInstance().logInvalidInputError(context, "Not all artifacts belongs to component " + component.getNormalizedName(), ErrorSeverity.INFO);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+        }
+
+        return Either.left(true);
+
+    }
+
+    /**
+     * verify that the members are component instances of the component
+     *
+     * @param component
+     * @param groupMembers
+     * @param memberToscaTypes
+     * @return
+     */
+    private Either<Boolean, ResponseFormat> verifyComponentInstancesAreValidMembers(Component component, String groupName, Map<String, String> groupMembers, List<String> memberToscaTypes) {
+
+        if (MapUtils.isEmpty(groupMembers)) {
+            return Either.left(true);
+        }
+
+        if (CollectionUtils.isEmpty(memberToscaTypes)) {
+            return Either.left(true);
+        }
+
+        List<ComponentInstance> componentInstances = component.getComponentInstances();
+        if (CollectionUtils.isNotEmpty(componentInstances)) {
+            Map<String, ComponentInstance> compInstUidToCompInstMap = componentInstances.stream().collect(Collectors.toMap(p -> p.getUniqueId(), p -> p));
+
+            Set<String> allCompInstances = compInstUidToCompInstMap.keySet();
+
+            for (Entry<String, String> groupMember : groupMembers.entrySet()) {
+                String compName = groupMember.getKey();
+                String compUid = groupMember.getValue();
+
+                if (!allCompInstances.contains(compUid)) {
+                    /*
+                     * %1 - member name %2 - group name %3 - VF name %4 - component type [VF ]
+                     */
+                    String componentTypeForResponse = getComponentTypeForResponse(component);
+
+                    BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Not all group members exists under the component", ErrorSeverity.INFO);
+                    return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, compName, groupName, component.getNormalizedName(), componentTypeForResponse));
+                }
+            }
+        }
+
+        return Either.left(true);
+    }
+
+
+
+    /**
+     * Update GroupDefinition metadata
+     *
+     * @param componentId
+     * @param user
+     * @param componentType
+     * @param updatedGroup
+     * @param inTransaction
+     * @return
+     */
+    public Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(String componentId, User user, ComponentTypeEnum componentType, GroupDefinition updatedGroup, boolean inTransaction , boolean shouldLock) {
+
+        Either<GroupDefinition, ResponseFormat> result = null;
+        try {
+            // Validate user exist
+            Either<User, ResponseFormat> validateUserExists = validateUserExists(user.getUserId(), UPDATE_GROUP, inTransaction);
+            if (validateUserExists.isRight()) {
+                result = Either.right(validateUserExists.right().value());
+                return result;
+            }
+            // Validate component exist
+            Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(componentId, componentType, null);
+            if (validateComponent.isRight()) {
+                result = Either.right(validateComponent.right().value());
+                return result;
+            }
+            org.openecomp.sdc.be.model.Component component = validateComponent.left().value();
+            // validate we can work on component
+            Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, user.getUserId());
+            if (canWork.isRight()) {
+                result = Either.right(canWork.right().value());
+                return result;
+            }
+            List<GroupDefinition> currentGroups = component.getGroups();
+            if (CollectionUtils.isEmpty(currentGroups)) {
+                log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
+                result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
+                return result;
+            }
+            // Validate groups exists in the component
+            Optional<GroupDefinition> currentGroupOpt = currentGroups.stream().filter(g -> g.getUniqueId().equals(updatedGroup.getUniqueId())).findAny();
+            if (!currentGroupOpt.isPresent()) {
+                log.error("Failed to update the metadata of group {} on component {}. The status is {}. ", updatedGroup.getName(), component.getName(), ActionStatus.GROUP_IS_MISSING);
+                result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, updatedGroup.getName(), component.getName(), component.getComponentType().getValue()));
+                return result;
+            }
+            GroupDefinition currentGroup = currentGroupOpt.get();
+            if ( shouldLock ){
+                Either<Boolean, ResponseFormat> lockResult = lockComponent(componentId, component, "Update GroupDefinition Metadata");
+                if (lockResult.isRight()) {
+                    result = Either.right(lockResult.right().value());
+                    return result;
+                }
+            }
+            // Validate group type is vfModule
+            if (currentGroup.getType().equals(Constants.GROUP_TOSCA_HEAT)) {
+                log.error("Failed to update the metadata of group {}. Group type is {} and cannot be updated", currentGroup.getName(), currentGroup.getType());
+                ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, updatedGroup.getType());
+                result = Either.right(responseFormat);
+                return result;
+            }
+            result = updateGroupMetadata(component, currentGroup, updatedGroup);
+            return result;
+
+        } finally {
+            if (result.isLeft()) {
+                titanDao.commit();
+            } else {
+                titanDao.rollback();
+            }
+            if (shouldLock) {
+                graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
+            }
+        }
+    }
+
+    private Either<GroupDefinition, ResponseFormat> updateGroupMetadata(Component component, GroupDefinition currentGroup, GroupDefinition updatedGroup) {
+        String currentGroupName = currentGroup.getName();
+        Either<GroupDefinition, ResponseFormat> result = validateAndUpdateGroupMetadata(currentGroup, updatedGroup);
+
+        if (result.isRight()) {
+            log.debug("Failed to validate a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
+        }
+        if (result.isLeft()) {
+            result = updateGroup(component, currentGroup, currentGroupName);
+        }
+        return result;
+    }
+
+    private Either<GroupDefinition, ResponseFormat> updateGroup(Component component, GroupDefinition updatedGroup, String currentGroupName) {
+        Either<GroupDefinition, StorageOperationStatus> handleGroupRes;
+        Either<GroupDefinition, ResponseFormat> result = null;
+        if (updatedGroup.getName().equals(currentGroupName)) {
+            handleGroupRes = groupsOperation.updateGroup(component, updatedGroup);
+            if (handleGroupRes.isRight()) {
+                log.debug("Failed to update a metadata of the group {} on component {}. ", updatedGroup.getName(), component.getName());
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
+            }
+        } else {
+            StorageOperationStatus deleteStatus = groupsOperation.deleteGroup(component, currentGroupName);
+            if (deleteStatus != StorageOperationStatus.OK) {
+                log.debug("Failed to delete the group {} from component {}. ", updatedGroup.getName(), component.getName());
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteStatus)));
+            }
+            handleGroupRes = groupsOperation.addGroup(component, updatedGroup);
+            if (handleGroupRes.isRight()) {
+                log.debug("Failed to add the group {} to component {}. ", updatedGroup.getName(), component.getName());
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(handleGroupRes.right().value())));
+            }
+        }
+        if (result == null) {
+            result = Either.left(updatedGroup);
+        }
+        return result;
+    }
+
+    /**
+     * Validate and Update Group Property
+     *
+     * @param componentId
+     * @param groupUniqueId
+     * @param user
+     * @param componentType
+     * @param groupPropertiesToUpdate
+     * @param inTransaction
+     * @return
+     */
+    public Either<List<GroupProperty>, ResponseFormat> validateAndUpdateGroupProperties(String componentId, String groupUniqueId, User user, ComponentTypeEnum componentType, List<GroupProperty> groupPropertiesToUpdate, boolean inTransaction) {
+
+        Either<List<GroupProperty>, ResponseFormat> result = Either.left(groupPropertiesToUpdate);
+        try {
+            Optional<GroupDefinition> optionalGroupConnectedToVf = null;
+            GroupDefinition currentGroup = null;
+            StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentId, componentType.getNodeType());
+            if (lockResult != StorageOperationStatus.OK) {
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult, componentType), componentId));
+            }
+            if (result.isLeft()) {
+                // VF exist because lock succedded
+                Resource vf = (Resource) toscaOperationFacade.getToscaElement(componentId).left().value();
+                optionalGroupConnectedToVf =
+                        // All groups on resource
+                        vf.getGroups().stream().
+                        // Filter in group sent is part of VF groups
+                                filter(e -> e.getUniqueId().equals(groupUniqueId)).
+                                // Collect
+                                findAny();
+                if (!optionalGroupConnectedToVf.isPresent()) {
+                    result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupUniqueId, vf.getName(), ComponentTypeEnum.RESOURCE.getValue()));
+                }
+            }
+
+            if (result.isLeft()) {
+                currentGroup = optionalGroupConnectedToVf.get();
+                result = validateGroupPropertyAndResetEmptyValue(currentGroup, groupPropertiesToUpdate);
+            }
+            if (result.isLeft()) {
+                result = updateGroupPropertiesValue(componentId, currentGroup, groupPropertiesToUpdate, inTransaction);
+                if (result.isRight()) {
+                    BeEcompErrorManager.getInstance().logBeSystemError("Update GroupProperties");
+                    log.debug("failed to update Vf {}", componentId);
+                }
+            }
+
+        } catch (Exception e) {
+            log.debug("Error in validateAndUpdateGroupProperty {}", e);
+            result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        } finally {
+            graphLockOperation.unlockComponent(componentId, componentType.getNodeType());
+        }
+        return result;
+    }
+
+    private void resetEmptyValueWithDefaults(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
+        Map<String, GroupProperty> originalProperties =
+                // Stream of original properties from group
+                originalGroup.convertToGroupProperties().stream().
+                // Collecting to map with name as key
+                        collect(Collectors.toMap(e -> e.getName(), e -> e));
+        for (GroupProperty gp : groupPropertiesToUpdate) {
+            if (StringUtils.isEmpty(gp.getValue())) {
+                gp.setValue(originalProperties.get(gp.getName()).getDefaultValue());
+            }
+        }
+
+    }
+
+    private Either<List<GroupProperty>, ResponseFormat> validateGroupPropertyAndResetEmptyValue(GroupDefinition originalGroup, List<GroupProperty> groupPropertiesToUpdate) {
+
+        Either<List<GroupProperty>, ResponseFormat> ret = validateOnlyValueChanged(groupPropertiesToUpdate, originalGroup);
+        if (ret.isLeft()) {
+            resetEmptyValueWithDefaults(groupPropertiesToUpdate, originalGroup);
+        }
+        if (ret.isLeft()) {
+            // Validate Type Match Value
+            Optional<StorageOperationStatus> optionalError =
+                    // Stream of group properties
+                    groupPropertiesToUpdate.stream().
+                    // Validate each and map to returned Strorage status value
+                            map(e -> groupOperation.validateAndUpdatePropertyValue(e)).
+                            // Keep only failed result if there is such
+                            filter(e -> e != StorageOperationStatus.OK).
+                            // collect
+                            findFirst();
+            if (optionalError.isPresent()) {
+                ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(optionalError.get());
+                ret = Either.right(componentsUtils.getResponseFormat(actionStatus));
+            }
+
+        }
+        if (ret.isLeft()) {
+            // Validate min max ect...
+            ret = validatePropertyBusinessLogic(groupPropertiesToUpdate, originalGroup);
+        }
+
+        return ret;
+    }
+
+    private Either<List<GroupProperty>, ResponseFormat> validatePropertyBusinessLogic(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
+
+        Either<List<GroupProperty>, ResponseFormat> ret = Either.left(groupPropertiesToUpdate);
+
+        Map<PropertyNames, String> nameValueMap = new HashMap<>();
+        for (GroupProperty gp : groupPropertiesToUpdate) {
+            // Filter out non special properties which does not have Enum
+            final PropertyNames gpEnum = PropertyNames.findName(gp.getName());
+            if (gpEnum != null) {
+                nameValueMap.put(gpEnum, gp.getValue());
+            }
+        }
+
+        if (!MapUtils.isEmpty(nameValueMap)) {
+
+            if (nameValueMap.containsKey(PropertyNames.INITIAL_COUNT) || nameValueMap.containsKey(PropertyNames.MAX_INSTANCES) || nameValueMap.containsKey(PropertyNames.MIN_INSTANCES)) {
+
+                Map<PropertyNames, String> oldValueMap = prepareMapWithOriginalProperties(originalGroup);
+
+                Either<Boolean, ResponseFormat> eitherValid = validateMinMaxAndInitialCountPropertyLogicVF(nameValueMap, oldValueMap);
+                if (eitherValid.isRight()) {
+                    ret = Either.right(eitherValid.right().value());
+                }
+            }
+            if (ret.isLeft() && (nameValueMap.containsKey(PropertyNames.VF_MODULE_DESCRIPTION) || nameValueMap.containsKey(PropertyNames.VF_MODULE_LABEL))) {
+
+                Optional<ResponseFormat> optionalError =
+                        // Stream of group Properties
+                        groupPropertiesToUpdate.stream().
+                        // Filter in only properties that needs text validation
+                                filter(e -> enumHasValueFilter(e.getName(), enumName -> PropertyNames.findName(enumName), PropertyNames.VF_MODULE_DESCRIPTION, PropertyNames.VF_MODULE_LABEL)).
+                                // validate text properties
+                                map(e -> validateFreeText(e)).
+                                // filter in only errors if exist
+                                filter(e -> e.isRight()).
+                                // map the Either value to the Error
+                                map(e -> e.right().value())
+                                // collect
+                                .findFirst();
+                if (optionalError.isPresent()) {
+                    ret = Either.right(optionalError.get());
+                }
+
+            }
+        }
+
+        return ret;
+    }
+
+    private Map<PropertyNames, String> prepareMapWithOriginalProperties(GroupDefinition originalGroup) {
+        Map<PropertyNames, String> oldValueMap = new HashMap<>();
+        PropertyNames[] propertiesToCheck = new PropertyNames[] { PropertyNames.INITIAL_COUNT, PropertyNames.MAX_INSTANCES, PropertyNames.MIN_INSTANCES };
+
+        for (GroupProperty gp : originalGroup.convertToGroupProperties()) {
+            if (enumHasValueFilter(gp.getName(), PropertyNames::findName, propertiesToCheck)) {
+                oldValueMap.put(PropertyNames.findName(gp.getName()), gp.getValue());
+            }
+        }
+        if (StringUtils.isEmpty(oldValueMap.get(PropertyNames.MAX_INSTANCES))) {
+            oldValueMap.put(PropertyNames.MAX_INSTANCES, String.valueOf(Integer.MAX_VALUE));
+        }
+        return oldValueMap;
+    }
+
+    private Either<List<GroupProperty>, ResponseFormat> validateOnlyValueChanged(List<GroupProperty> groupPropertiesToUpdate, GroupDefinition originalGroup) {
+
+        Either<List<GroupProperty>, ResponseFormat> ret = Either.left(groupPropertiesToUpdate);
+        if (CollectionUtils.isEmpty(groupPropertiesToUpdate)) {
+            ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, StringUtils.EMPTY));
+        } else if (CollectionUtils.isEmpty(originalGroup.getProperties())) {
+            ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, groupPropertiesToUpdate.get(NumberUtils.INTEGER_ZERO).getName()));
+        } else {
+            Map<String, GroupProperty> namePropertyMap =
+                    // Original Group Properties Stream
+                    originalGroup.convertToGroupProperties().stream().
+                    // Collect to map with name as key
+                            collect(Collectors.toMap(e -> e.getName(), e -> e));
+
+            Optional<GroupProperty> optionalMissingProperty =
+                    // Group Properties to be updated Stream
+                    groupPropertiesToUpdate.stream().
+                    // Filter in property that is not contained in original if there is such
+                            filter(e -> !namePropertyMap.containsKey(e.getName())).
+                            // collect
+                            findFirst();
+
+            if (optionalMissingProperty.isPresent()) {
+                ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, optionalMissingProperty.get().getName()));
+            } else {
+                Optional<GroupProperty> optionalNonValueChange =
+                        // groups to be updated stream
+                        groupPropertiesToUpdate.stream().
+                        // filter in only properties with non-value (illegal) change
+                                filter(e -> !isOnlyGroupPropertyValueChanged(e, namePropertyMap.get(e.getName()))).
+                                // Collect
+                                findFirst();
+                if (optionalNonValueChange.isPresent()) {
+                    ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY, optionalNonValueChange.get().getName()));
+
+                }
+            }
+
+        }
+        return ret;
+    }
+
+    /**
+     * if groupProperty are the same or if only value is different returns true, otherwise returns false.
+     *
+     * @param groupProperty
+     * @param groupProperty2
+     * @return
+     */
+    private boolean isOnlyGroupPropertyValueChanged(GroupProperty groupProperty, GroupProperty groupProperty2) {
+        // Create 2 duplicates for groupPropery and reset their values
+        try {
+            GroupProperty groupPropertyDuplicate = new GroupProperty(groupProperty);
+            groupPropertyDuplicate.setValue(null);
+            groupPropertyDuplicate.setSchema(null);
+            groupPropertyDuplicate.setParentUniqueId(null);
+            GroupProperty groupProperty2Duplicate = new GroupProperty(groupProperty2);
+            groupProperty2Duplicate.setValue(null);
+            groupProperty2Duplicate.setSchema(null);
+            groupProperty2Duplicate.setParentUniqueId(null);
+            return groupPropertyDuplicate.equals(groupProperty2Duplicate) && StringUtils.equals(groupPropertyDuplicate.getValueUniqueUid(), groupProperty2Duplicate.getValueUniqueUid());
+        } catch (Exception e) {
+            log.debug("Failed validate group properties. ", e);
+            return false;
+        }
+    }
+
+    /**
+     * Validate and update GroupDefinition metadata
+     *
+     * @param currentGroup
+     * @param groupUpdate
+     * @return
+     **/
+    private Either<GroupDefinition, ResponseFormat> validateAndUpdateGroupMetadata(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
+        // Check if to update, and update GroupDefinition name.
+        Either<Boolean, ResponseFormat> response = validateAndUpdateGroupName(currentGroup, groupUpdate);
+        if (response.isRight()) {
+            ResponseFormat errorResponse = response.right().value();
+            return Either.right(errorResponse);
+        }
+
+        // Do not allow to update GroupDefinition version directly.
+        String versionUpdated = groupUpdate.getVersion();
+        String versionCurrent = currentGroup.getVersion();
+        if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
+            log.info("update Group: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
+        }
+
+        return Either.left(currentGroup);
+    }
+
+    /**
+     * Validate and update GroupDefinition name
+     *
+     * @param currentGroup
+     * @param groupUpdate
+     * @return
+     */
+    private Either<Boolean, ResponseFormat> validateAndUpdateGroupName(GroupDefinition currentGroup, GroupDefinition groupUpdate) {
+        String nameUpdated = groupUpdate.getName();
+        String nameCurrent = currentGroup.getName();
+        if (!nameCurrent.equals(nameUpdated)) {
+            Either<Boolean, ResponseFormat> validatNameResponse = validateGroupName(currentGroup.getName(), groupUpdate.getName() ,true);
+            if (validatNameResponse.isRight()) {
+                ResponseFormat errorRespons = validatNameResponse.right().value();
+                return Either.right(errorRespons);
+            }
+            currentGroup.setName(groupUpdate.getName());
+        }
+        return Either.left(true);
+    }
+
+    /**
+     * 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
+     * MyDesc was changed.
+     *
+     * @param currentGroupName
+     * @param groupUpdateName
+     * @return
+     */
+    private Either<Boolean, ResponseFormat> validateGroupName(String currentGroupName, String groupUpdateName , boolean isforceNameModification) {
+        try {
+            // Check if the group name is in old format.
+            if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupUpdateName).matches()) {
+                log.error("Group name {} is in old format", groupUpdateName);
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME, groupUpdateName));
+            }
+
+            // Check that name pats 1 and 3 did not changed (only the second
+            // part can be changed)
+            // But verify before that the current group format is the new one
+            if (!Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(currentGroupName).matches()) {
+                String[] split1 = currentGroupName.split(GROUP_DELIMITER_REGEX);
+                String currentResourceName = split1[0];
+                String currentCounter = split1[2];
+
+                String[] split2 = groupUpdateName.split(GROUP_DELIMITER_REGEX);
+                String groupUpdateResourceName = split2[0];
+                String groupUpdateCounter = split2[2];
+                if (!isforceNameModification){            //if not forced ,allow name prefix&suffix validation [no changes]
+                    if (!currentResourceName.equals(groupUpdateResourceName)) {
+                        return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentResourceName));
+                    }
+
+                    if (!currentCounter.equals(groupUpdateCounter)) {
+                        return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentCounter));
+                    }
+                }
+
+            }
+
+            return Either.left(true);
+        } catch (Exception e) {
+            log.error("Error valiadting group name", e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+        }
+    }
+
+
+    /**
+     * associate artifacts to a given group
+     *
+     * @param componentId
+     * @param userId
+     * @param componentType
+     * @param inTransaction
+     * @return
+     */
+    public Either<GroupDefinitionInfo, ResponseFormat> getGroupWithArtifactsById(ComponentTypeEnum componentType, String componentId, String groupId, String userId, boolean inTransaction) {
+
+        Either<GroupDefinitionInfo, ResponseFormat> result = null;
+
+        // Validate user exist
+        Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, GET_GROUP, true);
+
+        if (validateUserExists.isRight()) {
+            result = Either.right(validateUserExists.right().value());
+            return result;
+        }
+
+        // Validate component exist
+        org.openecomp.sdc.be.model.Component component = null;
+        String realComponentId = componentId;
+
+        try {
+            ComponentParametersView componentParametersView = new ComponentParametersView();
+            componentParametersView.disableAll();
+            componentParametersView.setIgnoreGroups(false);
+            componentParametersView.setIgnoreArtifacts(false);
+            componentParametersView.setIgnoreUsers(false);
+
+            Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
+            if (validateComponent.isRight()) {
+                result = Either.right(validateComponent.right().value());
+                return result;
+            }
+            component = validateComponent.left().value();
+
+            Either<GroupDefinition, StorageOperationStatus> groupEither = findGroupOnComponent(component, groupId);
+
+            if (groupEither.isRight()) {
+                log.debug("Faild to find group {} under component {}", groupId, component.getUniqueId());
+                BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "group  " + groupId + " not found under component " + component.getUniqueId(), ErrorSeverity.INFO);
+                String componentTypeForResponse = getComponentTypeForResponse(component);
+                result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupId, component.getSystemName(), componentTypeForResponse));
+                return result;
+            }
+            GroupDefinition group = groupEither.left().value();
+
+            Boolean isBase = null;
+            List<GroupProperty> props = group.convertToGroupProperties();
+            if (props != null && !props.isEmpty()) {
+                Optional<GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
+                if (isBasePropOp.isPresent()) {
+                    GroupProperty propIsBase = isBasePropOp.get();
+                    isBase = Boolean.parseBoolean(propIsBase.getValue());
+
+                } else {
+                    BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
+                }
+            }
+
+            List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
+            List<ArtifactDefinition> artifactsFromComponent = new ArrayList<>();
+            List<String> artifactsIds = group.getArtifacts();
+
+            Map<String, ArtifactDefinition> deploymentArtifacts = null;
+            if (MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
+                deploymentArtifacts = component.getDeploymentArtifacts().values().stream().collect(Collectors.toMap(a -> a.getUniqueId(), a -> a));
+            }
+
+            if (artifactsIds != null && !artifactsIds.isEmpty()) {
+                for (String id : artifactsIds) {
+                    if (MapUtils.isEmpty(deploymentArtifacts) || !deploymentArtifacts.containsKey(id)) {
+                        log.debug("Failed to get artifact {} . Status is {} ", id, StorageOperationStatus.NOT_FOUND);
+                        ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND));
+                        result = Either.right(responseFormat);
+                        return result;
+                    }
+                    artifactsFromComponent.add(deploymentArtifacts.get(id));
+                }
+                if (!artifactsFromComponent.isEmpty()) {
+                    for (ArtifactDefinition artifactDefinition : artifactsFromComponent) {
+                        ArtifactDefinitionInfo artifactDefinitionInfo = new ArtifactDefinitionInfo(artifactDefinition);
+                        artifacts.add(artifactDefinitionInfo);
+                    }
+                }
+
+            }
+            GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
+            resultInfo.setIsBase(isBase);
+            if (!artifacts.isEmpty()) {
+                resultInfo.setArtifacts(artifacts);
+            }
+            result = Either.left(resultInfo);
+
+            return result;
+
+        } finally {
+
+            if (!inTransaction) {
+
+                if (result == null || result.isRight()) {
+                    log.debug("Going to execute rollback on create group.");
+                    titanDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on create group.");
+                    titanDao.commit();
+                }
+
+            }
+
+        }
+
+    }
+
+    private Either<GroupDefinition, StorageOperationStatus> findGroupOnComponent(Component component, String groupId) {
+
+        Either<GroupDefinition, StorageOperationStatus> result = null;
+        if (CollectionUtils.isNotEmpty(component.getGroups())) {
+            Optional<GroupDefinition> foundGroup = component.getGroups().stream().filter(g -> g.getUniqueId().equals(groupId)).findFirst();
+            if (foundGroup.isPresent()) {
+                result = Either.left(foundGroup.get());
+            }
+        }
+        if (result == null) {
+            result = Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        return result;
+    }
+
+    public String getAsString(List<String> list) {
+
+        if (list == null || list.isEmpty()) {
+            return "";
+        }
+        StringBuilder builder = new StringBuilder();
+        list.forEach(p -> builder.append(p + ","));
+
+        String result = builder.toString();
+        return result.substring(0, result.length());
+
+    }
+
+
+    private Either<List<GroupProperty>, ResponseFormat> updateGroupPropertiesValue(String componentId, GroupDefinition currentGroup, List<GroupProperty> groupPropertyToUpdate, boolean inTransaction) {
+        Either<List<GroupProperty>, ResponseFormat> result;
+
+        Either<List<GroupProperty>, StorageOperationStatus> eitherUpdate = groupsOperation.updateGroupPropertiesOnComponent(componentId, currentGroup, groupPropertyToUpdate);
+        if (eitherUpdate.isRight()) {
+            ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(eitherUpdate.right().value());
+            result = Either.right(componentsUtils.getResponseFormat(actionStatus));
+        } else {
+            result = Either.left(eitherUpdate.left().value());
+        }
+        return result;
+    }
+
+    public Either<Boolean, ResponseFormat> validateGenerateVfModuleGroupNames(List<ArtifactTemplateInfo> allGroups, String resourceSystemName, int startGroupCounter) {
+        Either<Boolean, ResponseFormat> validateGenerateGroupNamesRes = Either.left(true);
+        Collections.sort(allGroups, (art1, art2) -> ArtifactTemplateInfo.compareByGroupName(art1, art2));
+        for (ArtifactTemplateInfo group : allGroups) {
+            Either<String, ResponseFormat> validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), startGroupCounter++);
+            if (validateGenerateGroupNameRes.isRight()) {
+                validateGenerateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value());
+                break;
+            }
+            group.setGroupName(validateGenerateGroupNameRes.left().value());
+        }
+        return validateGenerateGroupNamesRes;
+    }
+
+    /**
+     * Generate module name from resourceName, description and counter
+     *
+     * @param resourceSystemName
+     * @param description
+     * @param groupCounter
+     * @return
+     */
+    private Either<String, ResponseFormat> validateGenerateVfModuleGroupName(String resourceSystemName, String description, int groupCounter) {
+        Either<String, ResponseFormat> validateGenerateGroupNameRes;
+        if (resourceSystemName != null && description != null && Pattern.compile(Constants.MODULE_DESC_PATTERN).matcher(description).matches()) {
+            final String fileName = description.replaceAll(GROUP_DELIMITER_REGEX, "\\.");
+            validateGenerateGroupNameRes = Either.left(String.format(Constants.MODULE_NAME_FORMAT, resourceSystemName, FilenameUtils.removeExtension(fileName), groupCounter));
+        } else {
+            validateGenerateGroupNameRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME));
+        }
+        return validateGenerateGroupNameRes;
+    }
+
+    public Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNames(Map<String, GroupDefinition> groups, String resourceSystemName) {
+
+        Map<String, GroupDefinition> updatedNamesGroups = new HashMap<>();
+        Either<Map<String, GroupDefinition>, ResponseFormat> result = Either.left(updatedNamesGroups);
+        for (Entry<String, GroupDefinition> groupEntry : groups.entrySet()) {
+            GroupDefinition curGroup = groupEntry.getValue();
+            String groupType = curGroup.getType();
+            String groupName = groupEntry.getKey();
+            int counter;
+            String description;
+            Either<String, ResponseFormat> newGroupNameRes;
+            if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(groupName).matches()) {
+
+                if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupEntry.getKey()).matches()) {
+                    counter = Integer.parseInt(groupEntry.getKey().split(Constants.MODULE_NAME_DELIMITER)[1]);
+                    description = curGroup.getDescription();
+                } else {
+                    counter = getNextVfModuleNameCounter(updatedNamesGroups);
+                    description = groupName;
+                }
+                newGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, description, counter);
+                if (newGroupNameRes.isRight()) {
+                    log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
+                    result = Either.right(newGroupNameRes.right().value());
+                    break;
+                }
+                groupName = newGroupNameRes.left().value();
+                curGroup.setName(groupName);
+            }
+            updatedNamesGroups.put(groupName, curGroup);
+        }
+        return result;
+    }
+
+    public int getNextVfModuleNameCounter(Map<String, GroupDefinition> groups) {
+        int counter = 0;
+        if (groups != null && !groups.isEmpty()) {
+            counter = getNextVfModuleNameCounter(groups.values());
+        }
+        return counter;
+    }
+
+    public int getNextVfModuleNameCounter(Collection<GroupDefinition> groups) {
+        int counter = 0;
+        if (groups != null && !groups.isEmpty()) {
+            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())
+                    .map(group -> Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1])).collect(toList());
+            counter = (counters == null || counters.isEmpty()) ? 0 : counters.stream().max((a, b) -> Integer.compare(a, b)).get() + 1;
+        }
+        return counter;
+    }
+
+    public Either<List<GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesOnGraph(List<GroupDefinition> groups, Component component, boolean inTransaction) {
+        List<GroupDefinition> updatedGroups = new ArrayList<>();
+        Either<List<GroupDefinition>, ResponseFormat> result = Either.left(updatedGroups);
+
+        for (GroupDefinition group : groups) {
+            String groupType = group.getType();
+            String oldGroupName = group.getName();
+            String newGroupName;
+            Either<String, ResponseFormat> newGroupNameRes;
+            int counter;
+            if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(oldGroupName).matches()) {
+                counter = Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]);
+                newGroupNameRes = validateGenerateVfModuleGroupName(component.getSystemName(), group.getDescription(), counter);
+                if (newGroupNameRes.isRight()) {
+                    log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value());
+                    result = Either.right(newGroupNameRes.right().value());
+                    break;
+                }
+                newGroupName = newGroupNameRes.left().value();
+                group.setName(newGroupName);
+
+            }
+            updatedGroups.add(group);
+
+        }
+
+        result = Either.left(updatedGroups);
+        return result;
+    }
+
+
+    public Either<GroupDefinitionInfo, ResponseFormat> getGroupInstWithArtifactsById(ComponentTypeEnum componentType, String componentId, String componentInstanceId, String groupInstId, String userId, boolean inTransaction) {
+        Either<GroupDefinitionInfo, ResponseFormat> result = null;
+
+        // Validate user exist
+        Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, UPDATE_GROUP, true);
+
+        if (validateUserExists.isRight()) {
+            result = Either.right(validateUserExists.right().value());
+            return result;
+        }
+
+        // Validate component exist
+        org.openecomp.sdc.be.model.Component component = null;
+        String realComponentId = componentId;
+
+        try {
+            ComponentParametersView componentParametersView = new ComponentParametersView();
+            componentParametersView.disableAll();
+            componentParametersView.setIgnoreUsers(false);
+            componentParametersView.setIgnoreComponentInstances(false);
+            componentParametersView.setIgnoreArtifacts(false);
+
+            Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView);
+            if (validateComponent.isRight()) {
+                result = Either.right(validateComponent.right().value());
+                return result;
+            }
+            component = validateComponent.left().value();
+            Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceRes = findComponentInstanceAndGroupInstanceOnComponent(component, componentInstanceId, groupInstId);
+
+            if (findComponentInstanceAndGroupInstanceRes.isRight()) {
+                log.debug("Failed to get group {} . Status is {} ", groupInstId, findComponentInstanceAndGroupInstanceRes.right().value());
+                ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findComponentInstanceAndGroupInstanceRes.right().value()));
+                result = Either.right(responseFormat);
+                return result;
+            }
+
+            GroupInstance group = findComponentInstanceAndGroupInstanceRes.left().value().getRight();
+
+            Boolean isBase = null;
+            List<? extends GroupProperty> props = group.convertToGroupInstancesProperties();
+            if (props != null && !props.isEmpty()) {
+                Optional<? extends GroupProperty> isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny();
+                if (isBasePropOp.isPresent()) {
+                    GroupProperty propIsBase = isBasePropOp.get();
+                    isBase = Boolean.parseBoolean(propIsBase.getValue());
+
+                } else {
+                    BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO);
+                }
+            }
+
+            List<ArtifactDefinitionInfo> artifacts = new ArrayList<>();
+            List<String> artifactsIds = group.getArtifacts();
+            if (artifactsIds != null && !artifactsIds.isEmpty()) {
+
+                List<ComponentInstance> instances = component.getComponentInstances();
+                if (instances != null) {
+                    Optional<ComponentInstance> findFirst = instances.stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst();
+                    if (findFirst.isPresent()) {
+                        ComponentInstance ci = findFirst.get();
+                        Map<String, ArtifactDefinition> deploymentArtifacts = ci.getDeploymentArtifacts();
+                        for (String id : artifactsIds) {
+                            Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
+                            if (artOp.isPresent()) {
+                                artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
+                            }
+                        }
+                        List<String> instArtifactsIds = group.getGroupInstanceArtifacts();
+                        for (String id : instArtifactsIds) {
+                            Optional<ArtifactDefinition> artOp = deploymentArtifacts.values().stream().filter(a -> a.getUniqueId().equals(id)).findFirst();
+                            if (artOp.isPresent()) {
+                                artifacts.add(new ArtifactDefinitionInfo(artOp.get()));
+                            }
+                        }
+                    }
+
+                }
+            }
+            GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group);
+            resultInfo.setIsBase(isBase);
+            if (!artifacts.isEmpty()) {
+                resultInfo.setArtifacts(artifacts);
+            }
+            result = Either.left(resultInfo);
+
+            return result;
+
+        } finally {
+
+            if (!inTransaction) {
+
+                if (result == null || result.isRight()) {
+                    log.debug("Going to execute rollback on create group.");
+                    titanDao.rollback();
+                } else {
+                    log.debug("Going to execute commit on create group.");
+                    titanDao.commit();
+                }
+
+            }
+
+        }
+    }
+
+    private Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> findComponentInstanceAndGroupInstanceOnComponent(Component component, String componentInstanceId, String groupInstId) {
+
+        Either<ImmutablePair<ComponentInstance, GroupInstance>, StorageOperationStatus> result = null;
+        if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
+            Optional<GroupInstance> foundGroup;
+            Optional<ComponentInstance> foundComponent = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst();
+            if (foundComponent.isPresent() && CollectionUtils.isNotEmpty(foundComponent.get().getGroupInstances())) {
+                foundGroup = foundComponent.get().getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstId)).findFirst();
+                if (foundGroup.isPresent()) {
+                    result = Either.left(new ImmutablePair<>(foundComponent.get(), foundGroup.get()));
+                }
+            }
+        }
+        if (result == null) {
+            result = Either.right(StorageOperationStatus.NOT_FOUND);
+        }
+        return result;
+    }
+
+    private int getLatestIntProperty(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues, PropertyNames propertyKey) {
+        String value;
+        if (newValues.containsKey(propertyKey)) {
+            value = newValues.get(propertyKey);
+        } else {
+            value = parentValues.get(propertyKey);
+        }
+        return Integer.valueOf(value);
+    }
+
+    private boolean isPropertyChanged(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues, final PropertyNames minInstances) {
+        return newValues.containsKey(minInstances) && !newValues.get(minInstances).equals(parentValues.get(minInstances));
+    }
+
+    private Either<Boolean, ResponseFormat> validateMinMaxAndInitialCountPropertyLogicVF(Map<PropertyNames, String> newValues, Map<PropertyNames, String> parentValues) {
+
+        int latestMaxInstances = getLatestIntProperty(newValues, parentValues, PropertyNames.MAX_INSTANCES);
+        int latestInitialCount = getLatestIntProperty(newValues, parentValues, PropertyNames.INITIAL_COUNT);
+        int latestMinInstances = getLatestIntProperty(newValues, parentValues, PropertyNames.MIN_INSTANCES);
+        Either<Boolean, ResponseFormat> result = Either.left(true);
+
+        if (isPropertyChanged(newValues, parentValues, PropertyNames.INITIAL_COUNT) && result.isLeft()
+                && (latestInitialCount > latestMaxInstances || latestInitialCount < latestMinInstances)) {
+            result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_INITIAL_COUNT_PROPERTY_VALUE, PropertyNames.INITIAL_COUNT.getPropertyName(), String.valueOf(latestMinInstances), String.valueOf(latestMaxInstances)));
+        }
+        if (isPropertyChanged(newValues, parentValues, PropertyNames.MAX_INSTANCES) && result.isLeft() &&
+                latestMaxInstances < latestInitialCount) {
+            result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_PROPERTY_VALUE_LOWER_HIGHER, PropertyNames.MAX_INSTANCES.getPropertyName(), "higher", String.valueOf(latestInitialCount)));
+        }
+        if (isPropertyChanged(newValues, parentValues, PropertyNames.MIN_INSTANCES) &&
+                result.isLeft() && latestMinInstances > latestInitialCount) {
+            result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_PROPERTY_VALUE_LOWER_HIGHER, PropertyNames.MIN_INSTANCES.getPropertyName(), "lower", String.valueOf(latestInitialCount)));
+        }
+        return result;
+    }
+
+    private Either<Boolean, ResponseFormat> validateMinMaxAndInitialCountPropertyLogic(Map<PropertyNames, String> newValues, Map<PropertyNames, String> currValues, Map<PropertyNames, String> parentValues) {
+
+        Either<Boolean, ResponseFormat> result;
+        for (Entry<PropertyNames, String> entry : newValues.entrySet()) {
+            PropertyNames currPropertyName = entry.getKey();
+            if (currPropertyName == PropertyNames.MIN_INSTANCES) {
+                String minValue = parentValues.get(PropertyNames.MIN_INSTANCES);
+                String maxValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
+                result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
+                        new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
+                if (result.isRight()) {
+                    return result;
+                }
+            } else if (currPropertyName == PropertyNames.INITIAL_COUNT) {
+                String minValue = newValues.containsKey(PropertyNames.MIN_INSTANCES) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.MIN_INSTANCES);
+                String maxValue = newValues.containsKey(PropertyNames.MAX_INSTANCES) ? newValues.get(PropertyNames.MAX_INSTANCES) : currValues.get(PropertyNames.MAX_INSTANCES);
+                result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
+                        new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
+                if (result.isRight()) {
+                    return result;
+                }
+            } else if (currPropertyName == PropertyNames.MAX_INSTANCES) {
+                String minValue = newValues.containsKey(PropertyNames.INITIAL_COUNT) ? newValues.get(PropertyNames.MIN_INSTANCES) : currValues.get(PropertyNames.INITIAL_COUNT);
+                String maxValue = parentValues.get(PropertyNames.MAX_INSTANCES);
+                result = validateValueInRange(new ImmutablePair<PropertyNames, String>(currPropertyName, entry.getValue()), new ImmutablePair<PropertyNames, String>(PropertyNames.MIN_INSTANCES, minValue),
+                        new ImmutablePair<PropertyNames, String>(PropertyNames.MAX_INSTANCES, maxValue));
+                if (result.isRight()) {
+                    return result;
+                }
+            }
+        }
+        return Either.left(true);
+    }
+
+    private Either<Boolean, ResponseFormat> validateValueInRange(ImmutablePair<PropertyNames, String> newValue, ImmutablePair<PropertyNames, String> min, ImmutablePair<PropertyNames, String> max) {
+        Either<Boolean, ResponseFormat> result;
+        final String warnMessage = "Failed to validate {} as property value of {}. It must be not higher than {}, and not lower than {}.";
+        int newValueInt = parseIntValue(newValue.getValue(), newValue.getKey());
+        int minInt = parseIntValue(min.getValue(), min.getKey());
+        int maxInt = parseIntValue(max.getValue(), max.getKey());
+        if (newValueInt < 0 || minInt < 0 || maxInt < 0) {
+            result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY));
+        } else if (newValueInt < minInt || newValueInt > maxInt) {
+            log.debug(warnMessage, newValue.getValue(), newValue.getKey().getPropertyName(), min.getValue(), max.getValue());
+            result = Either
+                    .right(componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_MIN_MAX_INSTANCES_PROPERTY_VALUE, newValue.getKey().getPropertyName(), maxInt == Integer.MAX_VALUE ? Constants.UNBOUNDED : max.getValue(), min.getValue()));
+        } else {
+            result = Either.left(true);
+        }
+        return result;
+    }
+
+    private int parseIntValue(String value, PropertyNames propertyName) {
+        int result;
+        if (propertyName == PropertyNames.MAX_INSTANCES) {
+            result = convertIfUnboundMax(value);
+        } else if (NumberUtils.isNumber(value)) {
+            result = Integer.parseInt(value);
+        } else {
+            result = -1;
+        }
+        return result;
+    }
+
+    /**
+     * validates received new property values and updates group instance in case of success
+     *
+     * @param oldGroupInstance
+     * @param newProperties
+     * @param inTransaction
+     * @return
+     */
+    public Either<GroupInstance, ResponseFormat> validateAndUpdateGroupInstancePropertyValues(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties, boolean inTransaction) {
+
+        Either<GroupInstance, ResponseFormat> actionResult = null;
+        Either<GroupInstance, StorageOperationStatus> updateGroupInstanceResult = null;
+        Either<List<GroupInstanceProperty>, ResponseFormat> validateRes = validateReduceGroupInstancePropertiesBeforeUpdate(oldGroupInstance, newProperties);
+        if (validateRes.isRight()) {
+            log.debug("Failed to validate group instance {} properties before update. ", oldGroupInstance.getName());
+            actionResult = Either.right(validateRes.right().value());
+        }
+        if (actionResult == null) {
+            List<GroupInstanceProperty> validatedReducedNewProperties = validateRes.left().value();
+            updateGroupInstanceResult = groupsOperation.updateGroupInstancePropertyValuesOnGraph(componentId, instanceId, oldGroupInstance, validatedReducedNewProperties);
+            if (updateGroupInstanceResult.isRight()) {
+                log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
+                actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateGroupInstanceResult.right().value())));
+            }
+        }
+        if (actionResult == null) {
+            actionResult = Either.left(updateGroupInstanceResult.left().value());
+        }
+        return actionResult;
+    }
+
+    private Either<List<GroupInstanceProperty>, ResponseFormat> validateReduceGroupInstancePropertiesBeforeUpdate(GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
+
+        Either<Boolean, ResponseFormat> validationRes = null;
+        Either<List<GroupInstanceProperty>, ResponseFormat> actionResult;
+        Map<String, GroupInstanceProperty> existingProperties = oldGroupInstance.convertToGroupInstancesProperties().stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
+        Map<PropertyNames, String> newPropertyValues = new EnumMap<>(PropertyNames.class);
+        List<GroupInstanceProperty> reducedProperties = new ArrayList<>();
+        String currPropertyName;
+        try {
+            for (GroupInstanceProperty currNewProperty : newProperties) {
+                currPropertyName = currNewProperty.getName();
+                validationRes = handleAndAddProperty(reducedProperties, newPropertyValues, currNewProperty, existingProperties.get(currPropertyName));
+                if (validationRes.isRight()) {
+                    log.debug("Failed to handle property {} of group instance {}. ", currPropertyName, oldGroupInstance.getName());
+                    break;
+                }
+            }
+            if (validationRes == null || validationRes.isLeft()) {
+                Map<PropertyNames, String> existingPropertyValues = new EnumMap<>(PropertyNames.class);
+                Map<PropertyNames, String> parentPropertyValues = new EnumMap<>(PropertyNames.class);
+                fillValuesAndParentValuesFromExistingProperties(existingProperties, existingPropertyValues, parentPropertyValues);
+                validationRes = validateMinMaxAndInitialCountPropertyLogic(newPropertyValues, existingPropertyValues, parentPropertyValues);
+            }
+            if (validationRes.isLeft()) {
+                actionResult = Either.left(reducedProperties);
+            } else {
+                actionResult = Either.right(validationRes.right().value());
+            }
+        } catch (Exception e) {
+            log.error("Exception occured during validation and reducing group instance properties. The message is {}", e.getMessage(), e);
+            actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+        return actionResult;
+    }
+
+    private void fillValuesAndParentValuesFromExistingProperties(Map<String, GroupInstanceProperty> existingProperties, Map<PropertyNames, String> propertyValues, Map<PropertyNames, String> parentPropertyValues) {
+        PropertyNames[] allPropertyNames = PropertyNames.values();
+        for (PropertyNames name : allPropertyNames) {
+            if (isUpdatable(name)) {
+                propertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getValue()));
+                parentPropertyValues.put(name, String.valueOf(existingProperties.get(name.getPropertyName()).getParentValue()));
+            }
+        }
+    }
+
+    private Either<Boolean, ResponseFormat> handleAndAddProperty(List<GroupInstanceProperty> reducedProperties, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty currNewProperty, GroupInstanceProperty currExistingProperty) {
+
+        Either<Boolean, ResponseFormat> validationRes = null;
+        String currPropertyName = currNewProperty.getName();
+        PropertyNames propertyName = PropertyNames.findName(currPropertyName);
+        try {
+            if (currExistingProperty == null) {
+                log.warn("The value of property with the name {} cannot be updated. The property not found on group instance. ", currPropertyName);
+            } else if (isUpdatable(propertyName)) {
+                validationRes = validateAndUpdatePropertyValue(currNewProperty, currExistingProperty);
+                if (validationRes.isRight()) {
+                    log.debug("Failed to validate property value {} of property {}. ", currNewProperty.getValue(), currPropertyName);
+                } else {
+                    addPropertyUpdatedValues(reducedProperties, propertyName, newPropertyValues, currNewProperty, currExistingProperty);
+                }
+            } else {
+                validateImmutableProperty(currExistingProperty, currNewProperty);
+            }
+            if (validationRes == null) {
+                validationRes = Either.left(true);
+            }
+        } catch (Exception e) {
+            log.error("Exception occured during handle and adding property. The message is {}", e.getMessage(), e);
+            validationRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+        return validationRes;
+    }
+
+    private boolean isUpdatable(PropertyNames updatablePropertyName) {
+        return updatablePropertyName != null && updatablePropertyName.getUpdateBehavior().getLevelNumber() >= GroupInstancePropertyValueUpdateBehavior.UPDATABLE_ON_SERVICE_LEVEL.getLevelNumber();
+    }
+
+    private void addPropertyUpdatedValues(List<GroupInstanceProperty> reducedProperties, PropertyNames propertyName, Map<PropertyNames, String> newPropertyValues, GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
+
+        String newValue = newProperty.getValue();
+        if (!newValue.equals(String.valueOf(existingProperty.getValue()))) {
+            newProperty.setValueUniqueUid(existingProperty.getValueUniqueUid());
+            reducedProperties.add(newProperty);
+        }
+        if (!isEmptyMinInitialCountValue(propertyName, newValue)) {
+            newPropertyValues.put(propertyName, newValue);
+        }
+    }
+
+    private boolean isEmptyMinInitialCountValue(PropertyNames propertyName, String newValue) {
+        boolean result = false;
+        if ((propertyName == PropertyNames.MIN_INSTANCES || propertyName == PropertyNames.INITIAL_COUNT) && !NumberUtils.isNumber(newValue)) {
+            result = true;
+        }
+        return result;
+    }
+
+    private int convertIfUnboundMax(String value) {
+
+        int result;
+        if (!NumberUtils.isNumber(value)) {
+            result = Integer.MAX_VALUE;
+        } else {
+            result = Integer.parseInt(value);
+        }
+        return result;
+    }
+
+    private Either<Boolean, ResponseFormat> validateAndUpdatePropertyValue(GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) {
+
+        Either<Boolean, ResponseFormat> validationRes = null;
+        String parentValue = existingProperty.getParentValue();
+
+        newProperty.setParentValue(parentValue);
+        if (StringUtils.isEmpty(newProperty.getValue())) {
+            newProperty.setValue(parentValue);
+        }
+        if (StringUtils.isEmpty(existingProperty.getValue())) {
+            existingProperty.setValue(parentValue);
+        }
+        StorageOperationStatus status = groupOperation.validateAndUpdatePropertyValue(newProperty);
+        if (status != StorageOperationStatus.OK) {
+            log.debug("Failed to validate property value {} of property with name {}. Status is {}. ", newProperty.getValue(), newProperty.getName(), status);
+            validationRes = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
+        }
+        if (validationRes == null) {
+            validationRes = Either.left(true);
+        }
+        return validationRes;
+    }
+
+    private void validateImmutableProperty(GroupProperty oldProperty, GroupProperty newProperty) {
+        if (oldProperty.getValue() == null && newProperty.getValue() != null || oldProperty.getValue() != null && !oldProperty.getValue().equals(newProperty.getValue())) {
+            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());
+        }
+    }
+
+    public GroupDefinition createGroup(String groupType, ComponentTypeEnum componentTypeEnum, String componentId,
+                                       String userId) {
+
+        try {
+            Component component = accessValidations.validateUserCanWorkOnComponentAndLockIt(componentTypeEnum, componentId, userId, CREATE_GROUP);
+
+            validateGroupTypePerComponent(groupType, component);
+
+            GroupTypeDefinition groupTypeDefinition = groupTypeOperation.getLatestGroupTypeByType(groupType, false)
+                    .left()
+                    .on(se -> onGroupTypeNotFound(component));
+
+            boolean isFirstGroup = component.getGroups() == null;
+            GroupDefinition groupDefinition = new GroupDefinition();
+            groupDefinition.setType(groupType);
+
+            //find next valid counter
+            int nextCounter = 0;
+            if (!isFirstGroup) {
+                nextCounter = getNewGroupCounter(component);
+            }
+            String name = TopologyTemplateOperation.buildSubComponentName(component.getName(), groupType, nextCounter);
+            groupDefinition.setName(name);
+
+            //Add default type properties
+            List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
+            List<GroupProperty> properties = groupTypeProperties.stream()
+                    .map(GroupProperty::new)
+                    .collect(toList());
+            groupDefinition.convertFromGroupProperties(properties);
+
+            List<GroupDefinition> gdList;
+            if (isFirstGroup) {
+                gdList = createGroups(component, Arrays.asList(groupDefinition))
+                        .left()
+                        .on(this::onFailedGroupDBOperation);
+            } else {
+                gdList = addGroups(component, Arrays.asList(groupDefinition))
+                        .left()
+                        .on(this::onFailedGroupDBOperation);
+            }
+            return gdList.get(0);
+        } finally {
+            titanDao.commit();
+            graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
+        }
+    }
+
+    private void validateGroupTypePerComponent(String groupType, Component component) {
+        String specificType = component.getComponentMetadataDefinition().getMetadataDataDefinition().getActualComponentType();
+        if (!component.isTopologyTemplate()) {
+            throw new ComponentException(ActionStatus.GROUP_TYPE_ILLEGAL_PER_COMPONENT, groupType,
+                    specificType);
+        }
+        Map<String, Set<String>> excludedGroupTypesMap = ConfigurationManager.getConfigurationManager().getConfiguration()
+                .getExcludedGroupTypesMapping();
+
+        if (MapUtils.isNotEmpty(excludedGroupTypesMap) && StringUtils.isNotEmpty(specificType)) {
+            Set<String> excludedGroupTypesPerComponent = excludedGroupTypesMap.get(specificType);
+            if (excludedGroupTypesPerComponent!=null && excludedGroupTypesPerComponent.contains(groupType)) {
+                throw new ComponentException(ActionStatus.GROUP_TYPE_ILLEGAL_PER_COMPONENT, groupType, specificType);
+            }
+        }
+    }
+
+    private int getNewGroupCounter(Component component) {
+        List<String> existingNames = component.getGroups()
+                .stream()
+                .map(GroupDataDefinition::getName)
+                .collect(toList());
+        List<String> existingIds = component.getGroups()
+                .stream()
+                .map(GroupDataDefinition::getUniqueId)
+                .collect(toList());
+        existingIds.addAll(existingNames);
+
+        return Utils.getNextCounter(existingIds);
+    }
+
+    public GroupDefinition updateGroup(ComponentTypeEnum componentTypeEnum, String componentId, String groupId,
+                                       String userId, GroupDefinition updatedGroup) {
+        try {
+            Component component = accessValidations.validateUserCanWorkOnComponentAndLockIt(componentTypeEnum, componentId, userId, UPDATE_GROUP);
+
+            GroupDefinition existingGroup = findGroupOnComponent(component, groupId)
+                    .left()
+                    .on(se -> onGroupNotFoundInComponentError(component, groupId));
+
+            String existingGroupName = existingGroup.getName();
+            String updatedGroupName = updatedGroup.getName();
+            assertNewNameIsValidAndUnique(existingGroupName, updatedGroupName, component);
+            existingGroup.setName(updatedGroupName);
+
+            return updateGroup(component, existingGroup, existingGroupName)
+                    .left()
+                    .on(this::onFailedUpdateGroupDBOperation);
+        } finally {
+            titanDao.commit();
+            graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
+        }
+
+    }
+
+    private void assertNewNameIsValidAndUnique(String currentGroupName, String updatedGroupName, Component component) {
+        if (!ValidationUtils.validateResourceInstanceNameLength(updatedGroupName)) {
+            throw new ComponentException(ActionStatus.EXCEEDS_LIMIT, "Group Name", ValidationUtils.RSI_NAME_MAX_LENGTH.toString());
+        }
+        if (!ValidationUtils.validateResourceInstanceName(updatedGroupName)) {
+            throw new ComponentException(ActionStatus.INVALID_VF_MODULE_NAME, updatedGroupName);
+        }
+        if (!ComponentValidations.validateNameIsUniqueInComponent(currentGroupName, updatedGroupName, component)) {
+            throw new ComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, "Group", updatedGroupName);
+        }
+    }
+
+    public GroupDefinition deleteGroup(ComponentTypeEnum componentTypeEnum, String componentId, String groupId,
+                                                                     String userId) {
+        try {
+            Component component = accessValidations.validateUserCanWorkOnComponentAndLockIt(componentTypeEnum, componentId, userId, DELETE_GROUP);
+
+            GroupDefinition groupDefinition = findGroupOnComponent(component, groupId)
+                    .left()
+                    .on(se -> onGroupNotFoundInComponentError(component, groupId));
+
+            List<GroupDefinition> gdList = deleteGroups(component, java.util.Arrays.asList(groupDefinition))
+                    .left()
+                    .on(this::onFailedGroupDBOperation);
+            return gdList.get(0);
+        } finally {
+            titanDao.commit();
+            graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
+        }
+    }
+
+    private List<GroupDefinition> onFailedGroupDBOperation(ResponseFormat responseFormat) {
+        titanDao.rollback();
+        throw new ComponentException(responseFormat);
+    }
+
+    private GroupDefinition onFailedUpdateGroupDBOperation(ResponseFormat responseFormat) {
+        titanDao.rollback();
+        throw new ComponentException(responseFormat);
+    }
+
+    private GroupDefinition onGroupNotFoundInComponentError(Component component, String groupId) {
+        throw new ComponentException(ActionStatus.GROUP_IS_MISSING, groupId,
+                component.getSystemName(), getComponentTypeForResponse(component));
+    }
+
+    private GroupTypeDefinition onGroupTypeNotFound(Component component) {
+        throw new ComponentException(ActionStatus.GROUP_TYPE_IS_INVALID, component.getSystemName(),
+                component.getComponentType().toString());
+    }
+
+    private Boolean onFailedToLockComponent(ResponseFormat responseFormat) {
+        throw new ComponentException(responseFormat);
+    }
+
+
+    public Either<List<GroupDefinition>, ResponseFormat> createGroups(Component component, final List<GroupDefinition> groupDefinitions) {
+
+        Map<String, GroupDataDefinition> groups = new HashMap<>();
+        Either<List<GroupDefinition>, ResponseFormat> result = null;
+        Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
+        Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+        if (allDataTypes.isRight()) {
+            TitanOperationStatus status = allDataTypes.right().value();
+            BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
+
+        }
+
+        // handle groups and convert to tosca data
+        if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
+            for (GroupDefinition groupDefinition : groupDefinitions) {
+                Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, groupDefinition, allDataTypes.left().value());
+                if (handleGroupRes.isRight()) {
+                    result = Either.right(handleGroupRes.right().value());
+                    break;
+                }
+                GroupDefinition handledGroup = handleGroupRes.left().value();
+                groups.put(handledGroup.getName(), new GroupDataDefinition(handledGroup));
+
+            }
+        }
+        if (result == null) {
+            createGroupsResult = groupsOperation.createGroups(component, groups);
+            if (createGroupsResult.isRight()) {
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
+            }
+        }
+        if (result == null) {
+            result = Either.left(createGroupsResult.left().value());
+        }
+        return result;
+    }
+
+    public Either<List<GroupDefinition>, ResponseFormat> addGroups(Component component, final List<GroupDefinition> groupDefinitions) {
+
+        Either<List<GroupDefinition>, ResponseFormat> result = null;
+        Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult = null;
+        List<GroupDataDefinition> groups = new ArrayList<>();
+
+        Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll();
+        if (allDataTypes.isRight()) {
+            TitanOperationStatus status = allDataTypes.right().value();
+            BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
+
+        }
+
+        // handle groups and convert to tosca data
+        if (groupDefinitions != null && !groupDefinitions.isEmpty()) {
+            for (GroupDefinition groupDefinition : groupDefinitions) {
+                Either<GroupDefinition, ResponseFormat> handleGroupRes = handleGroup(component, groupDefinition, allDataTypes.left().value());
+                if (handleGroupRes.isRight()) {
+                    result = Either.right(handleGroupRes.right().value());
+                    break;
+                }
+                GroupDefinition handledGroup = handleGroupRes.left().value();
+                groups.add(new GroupDataDefinition(handledGroup));
+            }
+        }
+        if (result == null) {
+            createGroupsResult = groupsOperation.addGroups(component, groups);
+            if (createGroupsResult.isRight()) {
+                result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
+            }
+        }
+        if (result == null) {
+            result = Either.left(createGroupsResult.left().value());
+        }
+        return result;
+    }
+
+    public Either<List<GroupDefinition>, ResponseFormat> deleteGroups(Component component, List<GroupDefinition> groupDefinitions) {
+
+        Either<List<GroupDefinition>, StorageOperationStatus> deleteGroupsResult;
+
+        deleteGroupsResult = groupsOperation.deleteGroups(component, groupDefinitions.stream().map(x -> new GroupDataDefinition(x)).collect(toList()));
+        if (deleteGroupsResult.isRight()) {
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteGroupsResult.right().value())));
+        }
+        return Either.left(deleteGroupsResult.left().value());
+    }
+
+    /**
+     * Update specific group version
+     *
+     */
+    public Either<List<GroupDefinition>, ResponseFormat> updateGroups(Component component, List<GroupDefinition> groupDefinitions) {
+
+        Either<List<GroupDefinition>, ResponseFormat> result = null;
+        Either<List<GroupDefinition>, StorageOperationStatus> createGroupsResult;
+
+        createGroupsResult = groupsOperation.updateGroups(component, groupDefinitions.stream().map(GroupDataDefinition::new).collect(toList()));
+        if (createGroupsResult.isRight()) {
+            result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(createGroupsResult.right().value())));
+        }
+
+        if (result == null) {
+            result = Either.left(createGroupsResult.left().value());
+        }
+        return result;
+    }
+
+    public Either<GroupDefinition, ResponseFormat> handleGroup(Component component, GroupDefinition groupDefinition, Map<String, DataTypeDefinition> allDAtaTypes) {
+
+        log.trace("Going to create group {}", groupDefinition);
+        // 3. verify group not already exist
+        String groupDefinitionName = groupDefinition.getName();
+        if (groupExistsInComponent(groupDefinitionName, component)) {
+            String componentTypeForResponse = getComponentTypeForResponse(component);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ALREADY_EXIST, groupDefinitionName, component.getNormalizedName(), componentTypeForResponse));
+        }
+        // 4. verify type of group exist
+        String groupType = groupDefinition.getType();
+        if (StringUtils.isEmpty(groupType)) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupDefinitionName));
+        }
+        Either<GroupTypeDefinition, StorageOperationStatus> getGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType, true);
+        if (getGroupType.isRight()) {
+            StorageOperationStatus status = getGroupType.right().value();
+            if (status == StorageOperationStatus.NOT_FOUND) {
+                BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "group type " + groupType + " cannot be found", ErrorSeverity.INFO);
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, groupType));
+            } else {
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+            }
+        }
+        // 6. verify the component instances type are allowed according to
+        // the member types in the group type
+        GroupTypeDefinition groupTypeDefinition = getGroupType.left().value();
+
+        Either<Boolean, ResponseFormat> areValidMembers = verifyComponentInstancesAreValidMembers(component, groupDefinitionName, groupDefinition.getMembers(), groupTypeDefinition.getMembers());
+
+        if (areValidMembers.isRight()) {
+            ResponseFormat responseFormat = areValidMembers.right().value();
+            return Either.right(responseFormat);
+        }
+        // 7. verify the artifacts belongs to the component
+        Either<Boolean, ResponseFormat> areValidArtifacts = verifyArtifactsBelongsToComponent(component, groupDefinition.getArtifacts(), CREATE_GROUP);
+        if (areValidArtifacts.isRight()) {
+            ResponseFormat responseFormat = areValidArtifacts.right().value();
+            return Either.right(responseFormat);
+        }
+        List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties();
+
+        List<GroupProperty> properties = groupDefinition.convertToGroupProperties();
+        List<GroupProperty> updatedGroupTypeProperties = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(properties)) {
+            if (CollectionUtils.isEmpty(groupTypeProperties)) {
+                BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "group type does not have properties", ErrorSeverity.INFO);
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.MATCH_NOT_FOUND))));
+            }
+
+            Map<String, PropertyDefinition> groupTypePropertiesMap = groupTypeProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p));
+
+            Either<GroupProperty, TitanOperationStatus> addPropertyResult;
+            int i = 1;
+            for (GroupProperty prop : properties) {
+                addPropertyResult = handleProperty(prop, groupTypePropertiesMap.get(prop.getName()), i, allDAtaTypes, groupType);
+                if (addPropertyResult.isRight()) {
+                    BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, "failed to validate property", ErrorSeverity.INFO);
+                    return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyResult.right().value()))));
+                }
+                updatedGroupTypeProperties.add(addPropertyResult.left().value());
+
+                i++;
+            }
+        }
+        if (groupDefinition.getUniqueId() == null) {
+            String uid = UniqueIdBuilder.buildGroupingUid(component.getUniqueId(), groupDefinitionName);
+            groupDefinition.setUniqueId(uid);
+        }
+        groupDefinition.convertFromGroupProperties(updatedGroupTypeProperties);
+        groupDefinition.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
+        groupDefinition.setGroupUUID(UniqueIdBuilder.generateUUID());
+        groupDefinition.setVersion(INITIAL_VERSION);
+        groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId());
+
+        return Either.left(groupDefinition);
+    }
+
+    private static boolean groupExistsInComponent(String groupDefinitionName, Component component) {
+        boolean found = false;
+        List<GroupDefinition> groups = component.getGroups();
+        if (CollectionUtils.isNotEmpty(groups)) {
+            found = groups.stream().filter(p -> p.getName().equalsIgnoreCase(groupDefinitionName)).findFirst().orElse(null) != null;
+        }
+        return found;
+    }
+
+    private Either<GroupProperty, TitanOperationStatus> handleProperty(GroupProperty groupProperty, PropertyDefinition prop, Integer index, Map<String, DataTypeDefinition> allDataTypes, String groupType) {
+
+        if (prop == null) {
+            return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+        }
+
+        PropertyDataDefinition propDataDef = prop;
+        String propertyType = propDataDef.getType();
+        String value = groupProperty.getValue();
+
+        Either<String, TitanOperationStatus> checkInnerType = propertyOperation.checkInnerType(propDataDef);
+        if (checkInnerType.isRight()) {
+            TitanOperationStatus status = checkInnerType.right().value();
+            return Either.right(status);
+        }
+
+        String innerType = checkInnerType.left().value();
+
+        log.debug("Before validateAndUpdatePropertyValue");
+        Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes);
+        log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid);
+
+        String newValue = value;
+        if (isValid.isRight()) {
+            Boolean res = isValid.right().value();
+            if (!res) {
+                return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT);
+            }
+        } else {
+            Object object = isValid.left().value();
+            if (object != null) {
+                newValue = object.toString();
+            }
+        }
+
+        String uniqueId = shouldReconstructUniqueId(groupType) ? UniqueIdBuilder.buildGroupPropertyValueUid(prop.getUniqueId(), index)
+                : prop.getUniqueId();
+
+        groupProperty.setUniqueId(uniqueId);
+        groupProperty.setValue(newValue);
+        groupProperty.setType(prop.getType());
+        groupProperty.setDefaultValue(prop.getDefaultValue());
+        groupProperty.setDescription(prop.getDescription());
+        groupProperty.setSchema(prop.getSchema());
+        groupProperty.setPassword(prop.isPassword());
+        groupProperty.setParentUniqueId(prop.getUniqueId());
+
+        log.debug("Before adding property value to graph {}", groupProperty);
+
+        return Either.left(groupProperty);
+    }
+
+    // For old groups we want to leave indexing of property
+    // For new groups we just need the types
+    private boolean shouldReconstructUniqueId(String groupType) {
+        return Constants.GROUP_TOSCA_HEAT.equals(groupType) || Constants.DEFAULT_GROUP_VF_MODULE.equals(groupType);
+    }
 
 }