Catalog alignment
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / GroupsOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
22
23 import fj.data.Either;
24 import org.apache.commons.collections.MapUtils;
25 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
26 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
27 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
28 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
30 import org.openecomp.sdc.be.datatypes.elements.*;
31 import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
32 import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
33 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
34 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
35 import org.openecomp.sdc.be.model.*;
36 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
37 import org.openecomp.sdc.be.model.operations.StorageException;
38 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
39 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
40 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
41 import org.openecomp.sdc.be.model.utils.GroupUtils;
42 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
43 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
44 import org.openecomp.sdc.common.log.wrappers.Logger;
45
46 import java.util.ArrayList;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Map.Entry;
50 import java.util.Optional;
51 import java.util.UUID;
52 import java.util.stream.Collectors;
53
54 @org.springframework.stereotype.Component("groups-operation")
55 public class GroupsOperation extends BaseOperation {
56
57     private static final Logger log = Logger.getLogger(GroupsOperation.class.getName());
58
59         public StorageOperationStatus deleteCalculatedCapabilitiesWithProperties(String componentId, List<GroupDefinition> groupDefinitions) {
60                 Optional<StorageOperationStatus> error = groupDefinitions.stream().map(g->removeCalculatedCapabilityFromComponent(componentId, g.getUniqueId())).filter(status-> status!=StorageOperationStatus.OK).findFirst();
61                 if(!error.isPresent()){
62                         Map<String, MapCapabilityProperty> extractCapabilityPropertiesFromGroups = ModelConverter.extractCapabilityPropertiesFromGroups(groupDefinitions, false);
63                         error = extractCapabilityPropertiesFromGroups.keySet().stream().map(k->removeCalculatedCapabilityPropertiesFromComponent(componentId, k)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
64                 }
65                 if(error.isPresent()){
66                         return error.get();
67                 }
68                 return StorageOperationStatus.OK;
69         }
70
71         /**
72          * Adds the map of the calculated capabilities and the map of the calculated capabilities properties the the component on the graph
73          * @param       componentId
74          * @param       calculatedCapabilities
75          * @param       calculatedCapabilitiesProperties
76          * @return      status of the result the operation
77          */
78         public StorageOperationStatus addCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
79
80                 Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream().map(e-> addElementToComponent(componentId, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
81                 if(!error.isPresent()){
82                         error = calculatedCapabilitiesProperties.entrySet().stream().map(e->addCalculatedCapabilityPropertiesToComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
83                 }
84                 if(error.isPresent()){
85                         return error.get();
86                 }
87                 return StorageOperationStatus.OK;
88         }
89         
90         public StorageOperationStatus updateCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
91
92                 Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream().map(e->updateCalculatedCapabilityOfComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
93                 if(!error.isPresent()){
94                         error = calculatedCapabilitiesProperties.entrySet().stream().map(e->updateCalculatedCapabilityPropertiesOnComponent(componentId, e)).filter(status-> status!=StorageOperationStatus.OK).findFirst();
95                 }
96                 if(error.isPresent()){
97                         return error.get();
98                 }
99                 return StorageOperationStatus.OK;
100         }
101
102         private StorageOperationStatus updateCalculatedCapabilityOfComponent(String componentId, Entry<String, MapListCapabilityDataDefinition> capabilities){
103                 if(MapUtils.isNotEmpty(capabilities.getValue().getMapToscaDataDefinition()))
104                         return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, capabilities.getValue(), capabilities.getKey());
105                 return StorageOperationStatus.OK;
106         }
107         
108         private StorageOperationStatus addCalculatedCapabilityPropertiesToComponent(String componentId, Entry<String, MapCapabilityProperty> properties){
109                 if(MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition()))
110                         return addToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(), properties.getKey());
111                 return StorageOperationStatus.OK;
112         }
113         
114         private StorageOperationStatus updateCalculatedCapabilityPropertiesOnComponent(String componentId, Entry<String, MapCapabilityProperty> properties){
115                 if(MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition()))
116                         return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(), properties.getKey());
117                 return StorageOperationStatus.OK;
118         }
119         
120         private StorageOperationStatus removeCalculatedCapabilityFromComponent(String componentId, String groupId){
121                 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, groupId);
122         }
123         
124         private StorageOperationStatus removeCalculatedCapabilityPropertiesFromComponent(String componentId, String groupId){
125                 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, groupId);
126         }
127
128
129     public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
130
131         Either<List<GroupDefinition>, StorageOperationStatus> result = null;
132         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
133         StorageOperationStatus status = null;
134
135                 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
136                 if (getComponentVertex.isRight()) {
137                         result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
138                 }
139         if (result == null) {
140             status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
141             if (status != StorageOperationStatus.OK) {
142                 result = Either.right(status);
143             }
144         }
145         if (result == null) {
146             result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
147         }
148         return result;
149     }
150
151     public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, List<T> groups) {
152         Either<List<GroupDefinition>, StorageOperationStatus> result = null;
153         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex;
154         StorageOperationStatus status;
155
156                 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
157                 if (getComponentVertex.isRight()) {
158                         result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
159                 }
160         if (result == null) {
161             status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
162
163             if (status != StorageOperationStatus.OK) {
164                 result = Either.right(status);
165             }
166         }
167
168         if (result == null) {
169                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap(GroupDataDefinition::getInvariantName, x->x));
170             result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
171         }
172         return result;
173     }
174
175     public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, List<GroupDataDefinition> groups) {
176         Either<List<GroupDefinition>, StorageOperationStatus> result = null;
177         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
178         StorageOperationStatus status = null;
179
180                 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
181                 if (getComponentVertex.isRight()) {
182                         result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
183                 }
184         if (result == null) {
185                         List<String> groupInvariantName = groups.stream().map(GroupDataDefinition::getInvariantName).collect(Collectors.toList());
186             status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupInvariantName);
187
188             if (status != StorageOperationStatus.OK) {
189                 result = Either.right(status);
190             }
191         }
192
193         if (result == null) {
194                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( GroupDataDefinition::getName, x->x));
195             result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
196         }
197         return result;
198     }
199
200     public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, List<T> groups, PromoteVersionEnum promoteVersion) {
201         Either<List<GroupDefinition>, StorageOperationStatus> result = null;
202         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
203         StorageOperationStatus status = null;
204
205                 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
206                 if (getComponentVertex.isRight()) {
207                         result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
208                 }
209         if (result == null) {
210             groups.forEach(gr -> {
211                 updateVersion(promoteVersion, gr);
212                // String groupUUID = UniqueIdBuilder.generateUUID();
213                // gr.setGroupUUID(groupUUID);
214             });
215
216             status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
217
218             if (status != StorageOperationStatus.OK) {
219                 result = Either.right(status);
220             }
221         }
222
223         if (result == null) {
224                         Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( GroupDataDefinition::getInvariantName, x->x));
225             result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
226             updateGroupsOnComponent(component, ModelConverter.convertToGroupDefinitions(mapGroup));
227         }
228         return result;
229     }
230
231     private void updateGroupsOnComponent(Component component, List<GroupDefinition> groupsToUpdate) {
232         List<GroupDefinition> groupsFromResource = component.getGroups();
233         for (GroupDefinition group : groupsToUpdate) {
234             Optional<GroupDefinition> op = groupsFromResource.stream()
235                     .filter(p -> p.getInvariantName()
236                             .equalsIgnoreCase(group.getInvariantName()))
237                     .findAny();
238             if (op.isPresent()) {
239                 GroupDefinition groupToUpdate = op.get();
240                 groupToUpdate.setMembers(group.getMembers());
241                 groupToUpdate.setCapabilities(group.getCapabilities());
242                 groupToUpdate.setProperties(group.getProperties());
243             }
244         }
245     }
246
247     private <T extends GroupDataDefinition> void updateVersion(PromoteVersionEnum promoteVersion, T group) {
248
249         group.setVersion(GroupUtils.updateVersion(promoteVersion, group.getVersion()));
250     }
251
252     public void updateGroupOnComponent(String componentId, GroupDefinition groupDefinition, PromoteVersionEnum promoteMinorVersion) {
253         GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
254                 .left()
255                 .on(this::onJanusGraphError);
256          updateVersion(promoteMinorVersion, groupDefinition);
257
258         StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groupDefinition,
259                 JsonPresentationFields.CI_INVARIANT_NAME);
260
261         if (StorageOperationStatus.OK != updateToscaResult) {
262             throw new StorageException(updateToscaResult, groupDefinition.getUniqueId());
263         }
264
265         updateLastUpdateDate(componentVertex);
266     }
267
268
269     public <T extends GroupDataDefinition> StorageOperationStatus updateGroupsOnComponent(String componentId, List<T> groups) {
270         GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
271                 .left()
272                 .on(this::onJanusGraphError);
273
274         StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
275
276
277         if (StorageOperationStatus.OK != updateToscaResult) {
278             throw new StorageException(updateToscaResult);
279         }
280
281         updateLastUpdateDate(componentVertex);
282
283         return updateToscaResult;
284
285     }
286
287     private void updateLastUpdateDate(GraphVertex componentVertex) {
288         componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
289         janusGraphDao.updateVertex(componentVertex)
290                 .left()
291                 .on(this::onJanusGraphError);
292     }
293
294     GraphVertex onJanusGraphError(JanusGraphOperationStatus janusGraphOperationStatus) {
295         throw new StorageException(
296                 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
297     }
298
299     public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties, PromoteVersionEnum promoteMinorVersion) {
300
301         Either<List<GroupProperty>, StorageOperationStatus> result = null;
302         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
303         GraphVertex componentVertex = null;
304
305                 getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
306                 if (getComponentVertex.isRight()) {
307                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
308                         result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
309                 }
310         if (result == null) {
311             componentVertex = getComponentVertex.left().value();
312             //update
313             List<PropertyDataDefinition> properties = group.getProperties();
314             newGroupProperties.forEach(np -> {
315                 Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
316                 if (currentProp.isPresent()) {
317                     currentProp.get().setValue(np.getValue());
318                 }
319             });
320             updateVersion(promoteMinorVersion, group);
321             StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.CI_INVARIANT_NAME);
322             if (updateDataRes != StorageOperationStatus.OK) {
323                 log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
324                 result = Either.right(updateDataRes);
325             }
326         }
327         if (result == null) {
328             componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
329             Either<GraphVertex, JanusGraphOperationStatus> updateRes = janusGraphDao.updateVertex(componentVertex);
330             if (updateRes.isRight()) {
331                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, updateRes.right().value());
332                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateRes.right().value()));
333             }
334         }
335         if (result == null) {
336             result = Either.left(newGroupProperties);
337         }
338         return result;
339     }
340
341
342
343     public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
344
345         Either<List<GroupInstance>, StorageOperationStatus> result = null;
346         StorageOperationStatus status = null;
347
348         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao
349             .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
350         if (getComponentVertex.isRight()) {
351             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
352         }
353         if (result == null) {
354             List<String> pathKeys = new ArrayList<>();
355             pathKeys.add(instanceId);
356             status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys, JsonPresentationFields.NAME);
357             if (status != StorageOperationStatus.OK) {
358                 result = Either.right(status);
359             }
360         }
361         if (result == null) {
362             result = Either.left(updatedGroupInstances);
363         }
364         return result;
365     }
366
367     public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
368         StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.CI_INVARIANT_NAME);
369         if (status != StorageOperationStatus.OK) {
370             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
371             return Either.right(status);
372         }
373         return Either.left(currentGroup);
374     }
375
376     public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
377         StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.CI_INVARIANT_NAME);
378         if (status != StorageOperationStatus.OK) {
379             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
380         }
381         return status;
382     }
383
384     public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup, PromoteVersionEnum promoteMinorVersion) {
385         updateVersion(promoteMinorVersion, currentGroup);
386         StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.CI_INVARIANT_NAME);
387         if (status != StorageOperationStatus.OK) {
388             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
389             return Either.right(status);
390         }
391         return Either.left(currentGroup);
392     }
393
394     public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
395
396         Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao
397             .getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
398         if (getComponentVertex.isRight()) {
399             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
400             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
401         }
402
403         List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
404         newProperties.forEach(np -> {
405             Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
406             if (prop.isPresent()) {
407                 prop.get().setValue(np.getValue());
408             }
409         });
410         GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
411         List<String> pathKeys = new ArrayList<>();
412         groupInstanceDataDefinition.setModificationTime(System.currentTimeMillis());
413         groupInstanceDataDefinition.setCustomizationUUID(UUID.randomUUID().toString());
414         pathKeys.add(instanceId);
415         StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
416         if (updateDataRes != StorageOperationStatus.OK) {
417             log.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
418             return Either.right(updateDataRes);
419         }
420         return Either.left(oldGroupInstance);
421     }
422 }