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.jsontitan.operations;
23 import java.util.ArrayList;
24 import java.util.List;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
29 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
30 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
31 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
32 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
33 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
34 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.GroupDefinition;
40 import org.openecomp.sdc.be.model.GroupInstance;
41 import org.openecomp.sdc.be.model.GroupInstanceProperty;
42 import org.openecomp.sdc.be.model.GroupProperty;
43 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
44 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
45 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
46 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
47 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
48 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 import fj.data.Either;
54 @org.springframework.stereotype.Component("groups-operation")
55 public class GroupsOperation extends BaseOperation {
57 private static final Logger log = LoggerFactory.getLogger(GroupsOperation.class);
59 public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, Map<String, GroupDataDefinition> groups) {
61 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
62 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
63 StorageOperationStatus status = null;
66 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
67 if (getComponentVertex.isRight()) {
68 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
72 status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
73 if (status != StorageOperationStatus.OK) {
74 result = Either.right(status);
78 result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
83 public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, List<GroupDataDefinition> groups) {
84 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
85 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
86 StorageOperationStatus status = null;
89 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
90 if (getComponentVertex.isRight()) {
91 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
95 status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
97 if (status != StorageOperationStatus.OK) {
98 result = Either.right(status);
102 if (result == null) {
103 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
104 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
109 public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, List<GroupDataDefinition> groups) {
110 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
111 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
112 StorageOperationStatus status = null;
114 if (result == null) {
115 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
116 if (getComponentVertex.isRight()) {
117 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
120 if (result == null) {
121 List<String> groupName = groups.stream().map(g -> g.getName()).collect(Collectors.toList());
122 status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupName);
124 if (status != StorageOperationStatus.OK) {
125 result = Either.right(status);
129 if (result == null) {
130 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
131 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
136 public <T extends GroupDataDefinition> Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, List<T> groups) {
137 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
138 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
139 StorageOperationStatus status = null;
141 if (result == null) {
142 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
143 if (getComponentVertex.isRight()) {
144 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
147 if (result == null) {
148 groups.forEach(gr -> {
149 String version = gr.getVersion();
150 String newVersion = increaseMajorVersion(version);
151 gr.setVersion(newVersion);
152 String groupUUID = UniqueIdBuilder.generateUUID();
153 gr.setGroupUUID(groupUUID);
156 status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
158 if (status != StorageOperationStatus.OK) {
159 result = Either.right(status);
163 if (result == null) {
164 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
165 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
171 public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties) {
173 Either<List<GroupProperty>,StorageOperationStatus> result = null;
174 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
175 GraphVertex componentVertex = null;
177 if (result == null) {
178 getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
179 if (getComponentVertex.isRight()) {
180 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
181 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
184 if (result == null) {
185 componentVertex = getComponentVertex.left().value();
187 List<PropertyDataDefinition> properties = group.getProperties();
188 newGroupProperties.forEach(np -> {
189 Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
190 if (currentProp.isPresent()) {
191 currentProp.get().setValue(np.getValue());
195 StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.NAME);
196 if ( updateDataRes != StorageOperationStatus.OK ){
197 log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
198 result = Either.right(updateDataRes);
201 if (result == null) {
202 componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
203 Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(componentVertex);
204 if (updateRes.isRight()) {
205 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, updateRes.right().value());
206 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
209 if (result == null) {
210 result = Either.left(newGroupProperties);
216 * The version of the group is an integer. In order to support BC, we might get a version in a float format.
221 private String increaseMajorVersion(String version) {
223 String[] versionParts = version.split(ToscaElementLifecycleOperation.VERSION_DELIMETER_REGEXP);
224 Integer majorVersion = Integer.parseInt(versionParts[0]);
228 return String.valueOf(majorVersion);
232 public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, List<GroupInstance> updatedGroupInstances) {
234 Either<List<GroupInstance>, StorageOperationStatus> result = null;
235 StorageOperationStatus status = null;
237 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
238 if (getComponentVertex.isRight()) {
239 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
241 if (result == null) {
242 List<String> pathKeys = new ArrayList<>();
243 pathKeys.add(instanceId);
244 status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys, JsonPresentationFields.NAME);
245 if (status != StorageOperationStatus.OK) {
246 result = Either.right(status);
249 if (result == null) {
250 result = Either.left(updatedGroupInstances);
255 public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
256 StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
257 if(status != StorageOperationStatus.OK){
258 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
259 return Either.right(status);
261 return Either.left(currentGroup);
264 public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
265 StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.NAME);
266 if(status != StorageOperationStatus.OK){
267 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
272 public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup) {
273 StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
274 if(status != StorageOperationStatus.OK){
275 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
276 return Either.right(status);
278 return Either.left(currentGroup);
281 public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
283 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
284 if (getComponentVertex.isRight()) {
285 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
286 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
289 List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
290 newProperties.forEach(np -> {
291 Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
292 if (prop.isPresent()) {
293 prop.get().setValue(np.getValue());
296 GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
297 List<String> pathKeys = new ArrayList<>();
298 pathKeys.add(instanceId);
299 StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
300 if (updateDataRes != StorageOperationStatus.OK) {
301 log.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
302 return Either.right(updateDataRes);
304 return Either.left(oldGroupInstance);