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.apache.tinkerpop.shaded.minlog.Log;
30 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
31 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
32 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
34 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
35 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
39 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
40 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
41 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
42 import org.openecomp.sdc.be.model.Component;
43 import org.openecomp.sdc.be.model.GroupDefinition;
44 import org.openecomp.sdc.be.model.GroupInstance;
45 import org.openecomp.sdc.be.model.GroupInstanceProperty;
46 import org.openecomp.sdc.be.model.GroupProperty;
47 import org.openecomp.sdc.be.model.User;
48 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
49 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
50 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
51 import org.openecomp.sdc.be.model.operations.impl.LifecycleOperation;
52 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
53 import org.openecomp.sdc.be.resources.data.GroupData;
54 import org.openecomp.sdc.common.api.Constants;
55 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
56 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 import com.carrotsearch.junitbenchmarks.annotation.LabelType;
61 import com.thinkaurelius.titan.diskstorage.Entry;
63 import fj.data.Either;
64 import javassist.expr.NewArray;
66 @org.springframework.stereotype.Component("groups-operation")
67 public class GroupsOperation extends BaseOperation {
69 private static Logger logger = LoggerFactory.getLogger(GroupsOperation.class.getName());
71 public Either<List<GroupDefinition>, StorageOperationStatus> createGroups(Component component, User user, ComponentTypeEnum componentType, Map<String, GroupDataDefinition> groups) {
73 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
74 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
75 StorageOperationStatus status = null;
78 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
79 if (getComponentVertex.isRight()) {
80 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
84 status = topologyTemplateOperation.associateGroupsToComponent(getComponentVertex.left().value(), groups);
85 if (status != StorageOperationStatus.OK) {
86 result = Either.right(status);
89 /* if (result == null) {
90 status = topologyTemplateOperation.associateGroupsPropertiesToComponent(getComponentVertex.left().value(), groupsProperties);
91 if (status != StorageOperationStatus.OK) {
92 result = Either.right(status);
96 result = Either.left(ModelConverter.convertToGroupDefinitions(groups));
101 public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
102 // TODO Auto-generated method stub
103 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
104 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
105 StorageOperationStatus status = null;
107 if (result == null) {
108 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
109 if (getComponentVertex.isRight()) {
110 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
113 if (result == null) {
114 status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
116 if (status != StorageOperationStatus.OK) {
117 result = Either.right(status);
121 if (result == null) {
122 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
123 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
128 public Either<List<GroupDefinition>, StorageOperationStatus> deleteGroups(Component component, User user, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
129 // TODO Auto-generated method stub
130 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
131 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
132 StorageOperationStatus status = null;
134 if (result == null) {
135 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
136 if (getComponentVertex.isRight()) {
137 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
140 if (result == null) {
141 List<String> groupName = groups.stream().map(g -> g.getName()).collect(Collectors.toList());
142 status = deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.GROUPS, groupName);
144 if (status != StorageOperationStatus.OK) {
145 result = Either.right(status);
149 if (result == null) {
150 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
151 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
156 public Either<List<GroupDefinition>, StorageOperationStatus> updateGroups(Component component, ComponentTypeEnum componentType, List<GroupDataDefinition> groups) {
157 // TODO Auto-generated method stub
158 Either<List<GroupDefinition>, StorageOperationStatus> result = null;
159 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
160 StorageOperationStatus status = null;
162 if (result == null) {
163 getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
164 if (getComponentVertex.isRight()) {
165 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
168 if (result == null) {
169 groups.forEach(gr -> {
170 String version = gr.getVersion();
171 String newVersion = increaseMajorVersion(version);
172 gr.setVersion(newVersion);
173 String groupUUID = UniqueIdBuilder.generateUUID();
174 gr.setGroupUUID(groupUUID);
177 status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.NAME);
179 if (status != StorageOperationStatus.OK) {
180 result = Either.right(status);
184 if (result == null) {
185 Map<String, GroupDataDefinition> mapGroup = groups.stream().collect(Collectors.toMap( x-> x.getName(), x->x));
186 result = Either.left(ModelConverter.convertToGroupDefinitions(mapGroup));
192 public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties) {
194 Either<List<GroupProperty>,StorageOperationStatus> result = null;
195 Either<GraphVertex, TitanOperationStatus> getComponentVertex = null;
196 GraphVertex componentVertex = null;
197 StorageOperationStatus status = null;
199 if (result == null) {
200 getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
201 if (getComponentVertex.isRight()) {
202 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
203 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
206 if (result == null) {
207 componentVertex = getComponentVertex.left().value();
209 List<PropertyDataDefinition> properties = group.getProperties();
210 newGroupProperties.forEach(np -> {
211 Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny();
212 if (currentProp.isPresent()) {
213 currentProp.get().setValue(np.getValue());
217 StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, JsonPresentationFields.NAME);
218 if ( updateDataRes != StorageOperationStatus.OK ){
219 logger.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes);
220 result = Either.right(updateDataRes);
223 if (result == null) {
224 componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
225 Either<GraphVertex, TitanOperationStatus> updateRes = titanDao.updateVertex(componentVertex);
226 if (updateRes.isRight()) {
227 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, updateRes.right().value());
228 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateRes.right().value()));
231 if (result == null) {
232 result = Either.left(newGroupProperties);
238 * The version of the group is an integer. In order to support BC, we might get a version in a float format.
243 private String increaseMajorVersion(String version) {
245 String[] versionParts = version.split(LifecycleOperation.VERSION_DELIMETER_REGEXP);
246 Integer majorVersion = Integer.parseInt(versionParts[0]);
250 return String.valueOf(majorVersion);
254 public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, ComponentTypeEnum componentType, String instanceId, List<GroupInstance> updatedGroupInstances) {
256 Either<List<GroupInstance>, StorageOperationStatus> result = null;
257 StorageOperationStatus status = null;
259 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(component.getUniqueId(), JsonParseFlagEnum.NoParse);
260 if (getComponentVertex.isRight()) {
261 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
263 if (result == null) {
264 List<String> pathKeys = new ArrayList<>();
265 pathKeys.add(instanceId);
266 status = updateToscaDataDeepElementsOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, updatedGroupInstances, pathKeys, JsonPresentationFields.NAME);
267 if (status != StorageOperationStatus.OK) {
268 result = Either.right(status);
271 if (result == null) {
272 result = Either.left(updatedGroupInstances);
277 public Either<GroupDefinition, StorageOperationStatus> updateGroup(Component component, GroupDefinition currentGroup) {
278 StorageOperationStatus status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
279 if(status != StorageOperationStatus.OK){
280 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
281 return Either.right(status);
283 return Either.left(currentGroup);
286 public StorageOperationStatus deleteGroup(Component component, String currentGroupName) {
287 StorageOperationStatus status = deleteToscaDataElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroupName, JsonPresentationFields.NAME);
288 if(status != StorageOperationStatus.OK){
289 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete group {} of component {}. The status is}. ", currentGroupName, component.getName(), status);
294 public Either<GroupDefinition, StorageOperationStatus> addGroup(Component component, GroupDefinition currentGroup) {
295 StorageOperationStatus status = addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, currentGroup, JsonPresentationFields.NAME);
296 if(status != StorageOperationStatus.OK){
297 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update group {} of component {}. The status is}. ", currentGroup.getName(), component.getName(), status);
298 return Either.right(status);
300 return Either.left(currentGroup);
303 public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) {
305 Either<GraphVertex, TitanOperationStatus> getComponentVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata);
306 if (getComponentVertex.isRight()) {
307 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId);
308 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
311 List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties();
312 newProperties.forEach(np -> {
313 Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst();
314 if (prop.isPresent()) {
315 prop.get().setValue(np.getValue());
318 GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance);
319 List<String> pathKeys = new ArrayList<>();
320 pathKeys.add(instanceId);
321 StorageOperationStatus updateDataRes = updateToscaDataDeepElementOfToscaElement(componentId, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, groupInstanceDataDefinition, pathKeys, JsonPresentationFields.NAME);
322 if (updateDataRes != StorageOperationStatus.OK) {
323 logger.debug("Failed to update properties for group instance {} error {}", oldGroupInstance.getName(), updateDataRes);
324 return Either.right(updateDataRes);
326 return Either.left(oldGroupInstance);