2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.List;
26 import java.util.Map.Entry;
27 import java.util.Optional;
28 import java.util.UUID;
29 import java.util.stream.Collectors;
30 import org.apache.commons.collections.MapUtils;
31 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
32 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
33 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
34 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
35 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
36 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
39 import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
41 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
42 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
43 import org.openecomp.sdc.be.model.Component;
44 import org.openecomp.sdc.be.model.GroupDefinition;
45 import org.openecomp.sdc.be.model.GroupInstance;
46 import org.openecomp.sdc.be.model.GroupInstanceProperty;
47 import org.openecomp.sdc.be.model.GroupProperty;
48 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
49 import org.openecomp.sdc.be.model.operations.StorageException;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
52 import org.openecomp.sdc.be.model.utils.GroupUtils;
53 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
54 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
55 import org.openecomp.sdc.common.log.wrappers.Logger;
57 @org.springframework.stereotype.Component("groups-operation")
58 public class GroupsOperation extends BaseOperation {
60 private static final Logger log = Logger.getLogger(GroupsOperation.class.getName());
62 public StorageOperationStatus deleteCalculatedCapabilitiesWithProperties(String componentId, List<GroupDefinition> groupDefinitions) {
63 Optional<StorageOperationStatus> error = groupDefinitions.stream()
64 .map(g -> removeCalculatedCapabilityFromComponent(componentId, g.getUniqueId())).filter(status -> status != StorageOperationStatus.OK)
66 if (!error.isPresent()) {
67 Map<String, MapCapabilityProperty> extractCapabilityPropertiesFromGroups = ModelConverter
68 .extractCapabilityPropertiesFromGroups(groupDefinitions, false);
69 error = extractCapabilityPropertiesFromGroups.keySet().stream()
70 .map(k -> removeCalculatedCapabilityPropertiesFromComponent(componentId, k)).filter(status -> status != StorageOperationStatus.OK)
73 if (error.isPresent()) {
76 return StorageOperationStatus.OK;
80 * Adds the map of the calculated capabilities and the map of the calculated capabilities properties the the component on the graph
83 * @param calculatedCapabilities
84 * @param calculatedCapabilitiesProperties
85 * @return status of the result the operation
87 public StorageOperationStatus addCalculatedCapabilitiesWithProperties(String componentId,
88 Map<String, MapListCapabilityDataDefinition> calculatedCapabilities,
89 Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
90 Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream()
91 .map(e -> addElementToComponent(componentId, VertexTypeEnum.CALCULATED_CAPABILITIES, EdgeLabelEnum.CALCULATED_CAPABILITIES, e))
92 .filter(status -> status != StorageOperationStatus.OK).findFirst();
93 if (!error.isPresent()) {
94 error = calculatedCapabilitiesProperties.entrySet().stream().map(e -> addCalculatedCapabilityPropertiesToComponent(componentId, e))
95 .filter(status -> status != StorageOperationStatus.OK).findFirst();
97 if (error.isPresent()) {
100 return StorageOperationStatus.OK;
103 public StorageOperationStatus updateCalculatedCapabilitiesWithProperties(String componentId,
104 Map<String, MapListCapabilityDataDefinition> calculatedCapabilities,
105 Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
106 Optional<StorageOperationStatus> error = calculatedCapabilities.entrySet().stream()
107 .map(e -> updateCalculatedCapabilityOfComponent(componentId, e)).filter(status -> status != StorageOperationStatus.OK).findFirst();
108 if (!error.isPresent()) {
109 error = calculatedCapabilitiesProperties.entrySet().stream().map(e -> updateCalculatedCapabilityPropertiesOnComponent(componentId, e))
110 .filter(status -> status != StorageOperationStatus.OK).findFirst();
112 if (error.isPresent()) {
115 return StorageOperationStatus.OK;
118 private StorageOperationStatus updateCalculatedCapabilityOfComponent(String componentId,
119 Entry<String, MapListCapabilityDataDefinition> capabilities) {
120 if (MapUtils.isNotEmpty(capabilities.getValue().getMapToscaDataDefinition())) {
121 return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, capabilities.getValue(),
122 capabilities.getKey());
124 return StorageOperationStatus.OK;
127 private StorageOperationStatus addCalculatedCapabilityPropertiesToComponent(String componentId, Entry<String, MapCapabilityProperty> properties) {
128 if (MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition())) {
129 return addToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
130 VertexTypeEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(), properties.getKey());
132 return StorageOperationStatus.OK;
135 private StorageOperationStatus updateCalculatedCapabilityPropertiesOnComponent(String componentId,
136 Entry<String, MapCapabilityProperty> properties) {
137 if (MapUtils.isNotEmpty(properties.getValue().getMapToscaDataDefinition())) {
138 return updateToscaDataDeepElementsBlockToToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, properties.getValue(),
139 properties.getKey());
141 return StorageOperationStatus.OK;
144 private StorageOperationStatus removeCalculatedCapabilityFromComponent(String componentId, String groupId) {
145 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES,
146 VertexTypeEnum.CALCULATED_CAPABILITIES, groupId);
149 private StorageOperationStatus removeCalculatedCapabilityPropertiesFromComponent(String componentId, String groupId) {
150 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
151 VertexTypeEnum.CALCULATED_CAP_PROPERTIES, groupId);
154 public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
155 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
156 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
157 StorageOperationStatus status = null;
158 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
159 if (getComponentVertex.isRight()) {
160 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
162 if (result == null) {
163 status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
164 if (status != StorageOperationStatus.OK) {
165 result = Either.right(status);
168 if (result == null) {
169 result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
174 public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, List<T> groups) {
175 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
176 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex;
177 StorageOperationStatus status;
178 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
179 if (getComponentVertex.isRight()) {
180 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
182 if (result == null) {
183 status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups,
184 JsonPresentationFields.CI_INVARIANT_NAME);
185 if (status != StorageOperationStatus.OK) {
186 result = Either.right(status);
189 if (result == null) {
190 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap(GroupDataDefinition::getInvariantName, x -> x));
191 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
196 public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, List<GroupDataDefinition> groups) {
197 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
198 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
199 StorageOperationStatus status = null;
200 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
201 if (getComponentVertex.isRight()) {
202 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
204 if (result == null) {
205 List<String> groupInvariantName = groups.stream().map(GroupDataDefinition::getInvariantName).collect(Collectors.toList());
206 status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupInvariantName);
207 if (status != StorageOperationStatus.OK) {
208 result = Either.right(status);
211 if (result == null) {
212 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap(GroupDataDefinition::getName, x -> x));
213 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
218 public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, List<T> groups,
219 PromoteVersionEnum promoteVersion) {
220 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
221 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
222 StorageOperationStatus status = null;
223 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
224 if (getComponentVertex.isRight()) {
225 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
227 if (result == null) {
228 groups.forEach(gr -> {
229 updateVersion(promoteVersion, gr);
230 // String groupUUID = UniqueIdBuilder.generateUUID();
232 // gr.setGroupUUID(groupUUID);
234 status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups,
235 JsonPresentationFields.CI_INVARIANT_NAME);
236 if (status != StorageOperationStatus.OK) {
237 result = Either.right(status);
240 if (result == null) {
241 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap(GroupDataDefinition::getInvariantName, x -> x));
242 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
243 updateGroupsOnComponent(component, ModelConverter.convertToGroupDefinitions(mapGroup));
248 private void updateGroupsOnComponent(Component component, List<GroupDefinition> groupsToUpdate) {
249 List<GroupDefinition> groupsFromResource = component.getGroups();
250 for (GroupDefinition group : groupsToUpdate) {
251 Optional<GroupDefinition> op = groupsFromResource.stream().filter(p -> p.getInvariantName().equalsIgnoreCase(group.getInvariantName()))
253 if (op.isPresent()) {
254 GroupDefinition groupToUpdate = op.get();
255 groupToUpdate.setMembers(group.getMembers());
256 groupToUpdate.setCapabilities(group.getCapabilities());
257 groupToUpdate.setProperties(group.getProperties());
262 private <T extends GroupDataDefinition> void updateVersion(PromoteVersionEnum promoteVersion, T group) {
263 group.setVersion(GroupUtils.updateVersion(promoteVersion, group.getVersion()));
266 public void updateGroupOnComponent(String componentId, GroupDefinition groupDefinition, PromoteVersionEnum promoteMinorVersion) {
267 GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata).left().on(this::onJanusGraphError);
268 updateVersion(promoteMinorVersion, groupDefinition);
269 StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS,
270 groupDefinition, JsonPresentationFields.CI_INVARIANT_NAME);
271 if (StorageOperationStatus.OK != updateToscaResult) {
272 throw new StorageException(updateToscaResult, groupDefinition.getUniqueId());
274 updateLastUpdateDate(componentVertex);
277 public <T extends GroupDataDefinition> StorageOperationStatus updateGroupsOnComponent(String componentId, List<T> groups) {
278 GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata).left().on(this::onJanusGraphError);
279 StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups,
280 JsonPresentationFields.CI_INVARIANT_NAME);
281 if (StorageOperationStatus.OK != updateToscaResult) {
282 throw new StorageException(updateToscaResult);
284 updateLastUpdateDate(componentVertex);
285 return updateToscaResult;
288 private void updateLastUpdateDate(GraphVertex componentVertex) {
289 componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
290 janusGraphDao.updateVertex(componentVertex).left().on(this::onJanusGraphError);
293 GraphVertex onJanusGraphError(JanusGraphOperationStatus janusGraphOperationStatus) {
294 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
297 public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group,
298 List<GroupProperty> newGroupProperties,
299 PromoteVersionEnum promoteMinorVersion) {
300 Either<List<GroupProperty>, StorageOperationStatus> result = null;
301 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
302 GraphVertex componentVertex = null;
303 getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
304 if (getComponentVertex.isRight()) {
305 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
306 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
308 if (result == null) {
309 componentVertex = getComponentVertex.left().value();
311 List<PropertyDataDefinition> properties = group.getProperties();
312 newGroupProperties.forEach(np -> {
313 Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
314 if (currentProp.isPresent()) {
315 currentProp.get().setValue(np.getValue());
316 currentProp.get().setToscaGetFunction(np.getToscaGetFunction());
317 currentProp.get().setToscaGetFunctionType(np.getToscaGetFunctionType());
320 updateVersion(promoteMinorVersion, group);
321 StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group,
322 JsonPresentationFields.CI_INVARIANT_NAME);
323 if (updateDataRes != StorageOperationStatus.OK) {
324 log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
325 result = Either.right(updateDataRes);
328 if (result == null) {
329 componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
330 Either<GraphVertex, JanusGraphOperationStatus> updateRes = janusGraphDao.updateVertex(componentVertex);
331 if (updateRes.isRight()) {
332 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId,
333 updateRes.right().value());
334 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateRes.right().value()));
337 if (result == null) {
338 result = Either.left(newGroupProperties);
343 public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId,
344 List<GroupInstance> updatedGroupInstances) {
345 Either<List<GroupInstance>, StorageOperationStatus> result = null;
346 StorageOperationStatus status = null;
347 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao
348 .getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
349 if (getComponentVertex.isRight()) {
350 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
352 if (result == null) {
353 List<String> pathKeys = new ArrayList<>();
354 pathKeys.add(instanceId);
355 status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
356 updatedGroupInstances, pathKeys, JsonPresentationFields.NAME);
357 if (status != StorageOperationStatus.OK) {
358 result = Either.right(status);
361 if (result == null) {
362 result = Either.left(updatedGroupInstances);
367 public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
368 StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS,
369 currentGroup, JsonPresentationFields.CI_INVARIANT_NAME);
370 if (status != StorageOperationStatus.OK) {
372 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(),
373 component.getName(), status);
374 return Either.right(status);
376 return Either.left(currentGroup);
379 public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
380 StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName,
381 JsonPresentationFields.CI_INVARIANT_NAME);
382 if (status != StorageOperationStatus.OK) {
383 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName,
384 component.getName(), status);
389 public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup,
390 PromoteVersionEnum promoteMinorVersion) {
391 updateVersion(promoteMinorVersion, currentGroup);
392 StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup,
393 JsonPresentationFields.CI_INVARIANT_NAME);
394 if (status != StorageOperationStatus.OK) {
396 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(),
397 component.getName(), status);
398 return Either.right(status);
400 return Either.left(currentGroup);
403 public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId,
404 GroupInstance oldGroupInstance,
405 List<GroupInstanceProperty> newProperties) {
406 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
407 if (getComponentVertex.isRight()) {
408 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
409 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
411 List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
412 newProperties.forEach(np -> {
413 Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
414 if (prop.isPresent()) {
415 prop.get().setValue(np.getValue());
418 GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
419 List<String> pathKeys = new ArrayList<>();
420 groupInstanceDataDefinition.setModificationTime(System.currentTimeMillis());
421 groupInstanceDataDefinition.setCustomizationUUID(UUID.randomUUID().toString());
422 pathKeys.add(instanceId);
423 StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS,
424 VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
425 if (updateDataRes != StorageOperationStatus.OK) {
426 log.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
427 return Either.right(updateDataRes);
429 return Either.left(oldGroupInstance);