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=========================================================
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
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;
46 import java.util.ArrayList;
47 import java.util.List;
49 import java.util.Map.Entry;
50 import java.util.Optional;
51 import java.util.UUID;
52 import java.util.stream.Collectors;
54 @org.springframework.stereotype.Component("groups-operation")
55 public class GroupsOperation extends BaseOperation {
57 private static final Logger log = Logger.getLogger(GroupsOperation.class.getName());
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();
65 if(error.isPresent()){
68 return StorageOperationStatus.OK;
72 * Adds the map of the calculated capabilities and the map of the calculated capabilities properties the the component on the graph
74 * @param calculatedCapabilities
75 * @param calculatedCapabilitiesProperties
76 * @return status of the result the operation
78 public StorageOperationStatus addCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
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();
84 if(error.isPresent()){
87 return StorageOperationStatus.OK;
90 public StorageOperationStatus updateCalculatedCapabilitiesWithProperties(String componentId, Map<String, MapListCapabilityDataDefinition> calculatedCapabilities, Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties) {
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();
96 if(error.isPresent()){
99 return StorageOperationStatus.OK;
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;
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;
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;
120 private StorageOperationStatus removeCalculatedCapabilityFromComponent(String componentId, String groupId){
121 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, groupId);
124 private StorageOperationStatus removeCalculatedCapabilityPropertiesFromComponent(String componentId, String groupId){
125 return deleteToscaDataDeepElementsBlockOfToscaElement(componentId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, groupId);
129 public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
131 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
132 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
133 StorageOperationStatus status = null;
135 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
136 if (getComponentVertex.isRight()) {
137 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
139 if (result == null) {
140 status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
141 if (status != StorageOperationStatus.OK) {
142 result = Either.right(status);
145 if (result == null) {
146 result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
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;
156 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
157 if (getComponentVertex.isRight()) {
158 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
160 if (result == null) {
161 status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
163 if (status != StorageOperationStatus.OK) {
164 result = Either.right(status);
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));
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;
180 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
181 if (getComponentVertex.isRight()) {
182 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
184 if (result == null) {
185 List<String> groupInvariantName = groups.stream().map(GroupDataDefinition::getInvariantName).collect(Collectors.toList());
186 status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupInvariantName);
188 if (status != StorageOperationStatus.OK) {
189 result = Either.right(status);
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));
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;
205 getComponentVertex = janusGraphDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
206 if (getComponentVertex.isRight()) {
207 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value()));
209 if (result == null) {
210 groups.forEach(gr -> {
211 updateVersion(promoteVersion, gr);
212 // String groupUUID = UniqueIdBuilder.generateUUID();
213 // gr.setGroupUUID(groupUUID);
216 status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
218 if (status != StorageOperationStatus.OK) {
219 result = Either.right(status);
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));
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()))
238 if (op.isPresent()) {
239 GroupDefinition groupToUpdate = op.get();
240 groupToUpdate.setMembers(group.getMembers());
241 groupToUpdate.setCapabilities(group.getCapabilities());
242 groupToUpdate.setProperties(group.getProperties());
247 private <T extends GroupDataDefinition> void updateVersion(PromoteVersionEnum promoteVersion, T group) {
249 group.setVersion(GroupUtils.updateVersion(promoteVersion, group.getVersion()));
252 public void updateGroupOnComponent(String componentId, GroupDefinition groupDefinition, PromoteVersionEnum promoteMinorVersion) {
253 GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
255 .on(this::onJanusGraphError);
256 updateVersion(promoteMinorVersion, groupDefinition);
258 StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groupDefinition,
259 JsonPresentationFields.CI_INVARIANT_NAME);
261 if (StorageOperationStatus.OK != updateToscaResult) {
262 throw new StorageException(updateToscaResult, groupDefinition.getUniqueId());
265 updateLastUpdateDate(componentVertex);
269 public <T extends GroupDataDefinition> StorageOperationStatus updateGroupsOnComponent(String componentId, List<T> groups) {
270 GraphVertex componentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata)
272 .on(this::onJanusGraphError);
274 StorageOperationStatus updateToscaResult = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME);
277 if (StorageOperationStatus.OK != updateToscaResult) {
278 throw new StorageException(updateToscaResult);
281 updateLastUpdateDate(componentVertex);
283 return updateToscaResult;
287 private void updateLastUpdateDate(GraphVertex componentVertex) {
288 componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
289 janusGraphDao.updateVertex(componentVertex)
291 .on(this::onJanusGraphError);
294 GraphVertex onJanusGraphError(JanusGraphOperationStatus janusGraphOperationStatus) {
295 throw new StorageException(
296 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
299 public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties, PromoteVersionEnum promoteMinorVersion) {
301 Either<List<GroupProperty>, StorageOperationStatus> result = null;
302 Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null;
303 GraphVertex componentVertex = null;
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()));
310 if (result == null) {
311 componentVertex = getComponentVertex.left().value();
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());
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);
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()));
335 if (result == null) {
336 result = Either.left(newGroupProperties);
343 public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
345 Either<List<GroupInstance>, StorageOperationStatus> result = null;
346 StorageOperationStatus status = null;
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()));
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);
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, 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);
373 return Either.left(currentGroup);
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);
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);
391 return Either.left(currentGroup);
394 public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
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()));
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());
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);
420 return Either.left(oldGroupInstance);