re base code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / HeatParametersOperation.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.operations.impl;
22
23 import fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.apache.tinkerpop.gremlin.structure.Edge;
26 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
27 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
28 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
29 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
30 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
33 import org.openecomp.sdc.be.model.HeatParameterDefinition;
34 import org.openecomp.sdc.be.model.heat.HeatParameterType;
35 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
36 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
37 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
38 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
39 import org.openecomp.sdc.be.resources.data.HeatParameterData;
40 import org.openecomp.sdc.be.resources.data.HeatParameterValueData;
41 import org.openecomp.sdc.be.resources.data.UniqueIdData;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.springframework.stereotype.Component;
44
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Map;
49
50 @Component("heat-parameter-operation")
51 public class HeatParametersOperation implements IHeatParametersOperation {
52
53     public static final String EMPTY_VALUE = null;
54
55     private static final Logger log = Logger.getLogger(HeatParametersOperation.class.getName());
56
57     @javax.annotation.Resource
58     private TitanGenericDao titanGenericDao;
59
60     public TitanGenericDao getTitanGenericDao() {
61         return titanGenericDao;
62     }
63
64     public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
65         this.titanGenericDao = titanGenericDao;
66     }
67
68     public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties) {
69
70         Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.HEAT_PARAMETER, NodeTypeEnum.HeatParameter,
71                 HeatParameterData.class);
72
73         if (childrenNodes.isRight()) {
74             TitanOperationStatus status = childrenNodes.right().value();
75             if (status == TitanOperationStatus.NOT_FOUND) {
76                 status = TitanOperationStatus.OK;
77             }
78             return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
79         }
80
81         List<ImmutablePair<HeatParameterData, GraphEdge>> values = childrenNodes.left().value();
82         if (values != null) {
83
84             for (ImmutablePair<HeatParameterData, GraphEdge> immutablePair : values) {
85                 GraphEdge edge = immutablePair.getValue();
86                 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
87                 if (log.isDebugEnabled())
88                     log.debug("Property {} is associated to node {}", propertyName, uniqueId);
89                 HeatParameterData propertyData = immutablePair.getKey();
90                 HeatParameterDefinition propertyDefinition = convertParameterDataToParameterDefinition(propertyData, propertyName, uniqueId);
91
92                 properties.add(propertyDefinition);
93
94                 if (log.isTraceEnabled()) {
95                     log.trace("getHeatParametersOfNode - property {} associated to node {}", propertyDefinition, uniqueId);
96                 }
97             }
98
99         }
100
101         return StorageOperationStatus.OK;
102     }
103
104     public StorageOperationStatus getParametersValueNodes(NodeTypeEnum parentNodeType, String parentUniqueId, List<HeatParameterValueData> heatValues) {
105
106         Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentUniqueId, GraphEdgeLabels.PARAMETER_VALUE,
107                 NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class);
108
109         if (childrenNodes.isRight()) {
110             TitanOperationStatus status = childrenNodes.right().value();
111             if (status == TitanOperationStatus.NOT_FOUND) {
112                 status = TitanOperationStatus.OK;
113             }
114             return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
115         }
116
117         List<ImmutablePair<HeatParameterValueData, GraphEdge>> values = childrenNodes.left().value();
118         if (values != null) {
119
120             for (ImmutablePair<HeatParameterValueData, GraphEdge> immutablePair : values) {
121                 GraphEdge edge = immutablePair.getValue();
122                 String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
123                 log.trace("Heat value {} is associated to node {}", propertyName,parentUniqueId);
124                 HeatParameterValueData propertyData = immutablePair.getKey();
125
126                 heatValues.add(propertyData);
127             }
128
129         }
130
131         return StorageOperationStatus.OK;
132     }
133
134     @Override
135     public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) {
136
137         List<HeatParameterDefinition> heatParams = new ArrayList<>();
138         StorageOperationStatus propertiesOfNodeRes = getHeatParametersOfNode(nodeType, uniqueId, heatParams);
139
140         if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
141             return Either.right(propertiesOfNodeRes);
142         }
143
144         for (HeatParameterDefinition propertyDefinition : heatParams) {
145
146             String propertyUid = propertyDefinition.getUniqueId();
147             Either<HeatParameterData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterFromGraph(propertyUid);
148             if (deletePropertyRes.isRight()) {
149                 log.error("Failed to delete heat parameter with id {}", propertyUid);
150                 TitanOperationStatus status = deletePropertyRes.right().value();
151                 if (status == TitanOperationStatus.NOT_FOUND) {
152                     status = TitanOperationStatus.INVALID_ID;
153                 }
154                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
155             }
156
157         }
158
159         log.debug("The heat parameters deleted from node {} are {}", uniqueId, heatParams);
160         return Either.left(heatParams);
161     }
162
163     @Override
164     public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId) {
165
166         List<HeatParameterValueData> heatValues = new ArrayList<>();
167         StorageOperationStatus propertiesOfNodeRes = getParametersValueNodes(parentNodeType, parentUniqueId, heatValues);
168
169         if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) {
170             return propertiesOfNodeRes;
171         }
172
173         for (HeatParameterValueData propertyDefinition : heatValues) {
174
175             String propertyUid = (String) propertyDefinition.getUniqueId();
176             Either<HeatParameterValueData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterValueFromGraph(propertyUid);
177             if (deletePropertyRes.isRight()) {
178                 log.error("Failed to delete heat parameter value with id {}", propertyUid);
179                 TitanOperationStatus status = deletePropertyRes.right().value();
180                 if (status == TitanOperationStatus.NOT_FOUND) {
181                     status = TitanOperationStatus.INVALID_ID;
182                 }
183                 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
184             }
185
186         }
187
188         log.debug("The heat values deleted from node {} are {}" , parentUniqueId, heatValues);
189         return StorageOperationStatus.OK;
190     }
191
192     private Either<HeatParameterData, TitanOperationStatus> deleteHeatParameterFromGraph(String propertyId) {
193         log.debug("Before deleting heat parameter from graph {}" , propertyId);
194         return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameter), propertyId, HeatParameterData.class);
195     }
196
197     private Either<HeatParameterValueData, TitanOperationStatus> deleteHeatParameterValueFromGraph(String propertyId) {
198         log.debug("Before deleting heat parameter from graph {}" , propertyId);
199         return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameterValue), propertyId, HeatParameterValueData.class);
200     }
201
202     @Override
203     public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String parentId, NodeTypeEnum nodeType) {
204
205         if (properties != null) {
206             for (HeatParameterDefinition propertyDefinition : properties) {
207
208                 String propertyName = propertyDefinition.getName();
209
210                 Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, parentId, nodeType);
211
212                 if (addPropertyToGraph.isRight()) {
213                     return DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value());
214                 }
215             }
216         }
217
218         return StorageOperationStatus.OK;
219
220     }
221
222     @Override
223     public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties) {
224
225         if (properties == null) {
226             return StorageOperationStatus.OK;
227         }
228         for (HeatParameterDefinition property : properties) {
229
230             HeatParameterData heatParameterData = new HeatParameterData(property);
231             Either<HeatParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterData, HeatParameterData.class);
232             if (updateNode.isRight()) {
233                 log.debug("failed to update heat parameter in graph. id = {}", property.getUniqueId());
234                 return DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
235             }
236         }
237
238         return StorageOperationStatus.OK;
239     }
240
241     public Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph(String propertyName, HeatParameterDefinition propertyDefinition, String parentId, NodeTypeEnum nodeType) {
242
243         UniqueIdData parentNode = new UniqueIdData(nodeType, parentId);
244
245         propertyDefinition.setUniqueId(UniqueIdBuilder.buildHeatParameterUniqueId(parentId, propertyName));
246         HeatParameterData propertyData = new HeatParameterData(propertyDefinition);
247
248         log.debug("Before adding property to graph {}" , propertyData);
249         Either<HeatParameterData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, HeatParameterData.class);
250         log.debug("After adding property to graph {}" , propertyData);
251         if (createNodeResult.isRight()) {
252             TitanOperationStatus operationStatus = createNodeResult.right().value();
253             log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
254             return Either.right(operationStatus);
255         }
256
257         Map<String, Object> props = new HashMap<>();
258         props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName);
259         Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(parentNode, propertyData, GraphEdgeLabels.HEAT_PARAMETER, props);
260         if (createRelResult.isRight()) {
261             TitanOperationStatus operationStatus = createRelResult.right().value();
262             log.error("Failed to associate {} {} to heat parameter {} in graph. status is {}", nodeType.getName(), parentId, propertyName, operationStatus);
263             return Either.right(operationStatus);
264         }
265
266         return Either.left(createNodeResult.left().value());
267
268     }
269
270     public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition propertyDefinition) {
271
272         log.trace("Going to validate property type and value. {}" , propertyDefinition);
273
274         String propertyType = propertyDefinition.getType();
275         HeatParameterType type = getType(propertyType);
276
277         if (type == null) {
278             log.info("The type {} of heat parameter is invalid", type);
279
280             return StorageOperationStatus.INVALID_TYPE;
281         }
282         propertyDefinition.setType(type.getType());
283
284         log.trace("After validating property type {}", propertyType);
285
286         // validate default value
287         String defaultValue = propertyDefinition.getDefaultValue();
288         boolean isValidProperty = isValidValue(type, defaultValue);
289         if (!isValidProperty) {
290             log.info("The value {} of property from type {} is invalid", defaultValue, type);
291             return StorageOperationStatus.INVALID_VALUE;
292         }
293
294         PropertyValueConverter converter = type.getConverter();
295
296         if (isEmptyValue(defaultValue)) {
297             log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName() , EMPTY_VALUE);
298
299             propertyDefinition.setDefaultValue(EMPTY_VALUE);
300         } else if (!isEmptyValue(defaultValue)) {
301             String convertedValue = converter.convert(defaultValue, null, null);
302             propertyDefinition.setDefaultValue(convertedValue);
303         }
304
305         // validate current value
306         String value = propertyDefinition.getCurrentValue();
307         isValidProperty = isValidValue(type, value);
308         if (!isValidProperty) {
309             log.info("The value {} of property from type {} is invalid", value, type);
310             return StorageOperationStatus.INVALID_VALUE;
311         }
312
313         if (isEmptyValue(value)) {
314             log.debug("Value was not sent for property {}. Set value to {}", propertyDefinition.getName(), EMPTY_VALUE);
315
316             propertyDefinition.setCurrentValue(EMPTY_VALUE);
317         } else if (!value.equals("")) {
318             String convertedValue = converter.convert(value, null, null);
319             propertyDefinition.setCurrentValue(convertedValue);
320         }
321
322         return StorageOperationStatus.OK;
323     }
324
325     public HeatParameterDefinition convertParameterDataToParameterDefinition(HeatParameterData propertyDataResult, String propertyName, String resourceId) {
326         log.debug("convert to HeatParamereDefinition {}", propertyDataResult);
327
328         HeatParameterDefinition propertyDefResult = new HeatParameterDefinition(propertyDataResult.getHeatDataDefinition());
329
330         propertyDefResult.setName(propertyName);
331
332         return propertyDefResult;
333     }
334
335     private HeatParameterType getType(String propertyType) {
336
337         return HeatParameterType.isValidType(propertyType);
338
339     }
340
341     protected boolean isValidValue(HeatParameterType type, String value) {
342         if (isEmptyValue(value)) {
343             return true;
344         }
345
346         PropertyTypeValidator validator = type.getValidator();
347
348         boolean isValid = validator.isValid(value, null, null);
349         if (isValid) {
350             return true;
351         } else {
352             return false;
353         }
354
355     }
356
357     public boolean isEmptyValue(String value) {
358         if (value == null) {
359             return true;
360         }
361         return false;
362     }
363
364     public boolean isNullParam(String value) {
365         if (value == null) {
366             return true;
367         }
368         return false;
369     }
370
371     @Override
372     public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
373         String heatEnvId = UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParam.getName());
374         Either<HeatParameterValueData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatEnvId, HeatParameterValueData.class);
375         if (getNode.isRight() || getNode.left().value() == null) {
376             if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
377                 log.debug("Updated heat parameter value equals default value. No need to create heat parameter value for heat parameter {}", heatParam.getUniqueId());
378                 return Either.left(null);
379             }
380             return createHeatParameterValue(heatParam, artifactId, resourceInstanceId, artifactLabel);
381         } else {
382             heatParam.setUniqueId(heatEnvId);
383             return updateHeatParameterValue(heatParam);
384         }
385     }
386
387     public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam) {
388         HeatParameterValueData heatParameterValue = new HeatParameterValueData();
389         heatParameterValue.setUniqueId(heatParam.getUniqueId());
390         if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) {
391             Either<GraphRelation, TitanOperationStatus> deleteParameterValueIncomingRelation = titanGenericDao.deleteIncomingRelationByCriteria(heatParameterValue, GraphEdgeLabels.PARAMETER_VALUE, null);
392             if (deleteParameterValueIncomingRelation.isRight()) {
393                 log.debug("Failed to delete heat parameter value incoming relation on graph. id = {}", heatParameterValue.getUniqueId());
394                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteParameterValueIncomingRelation.right().value()));
395             }
396             Either<Edge, TitanOperationStatus> getOutgoingRelation = titanGenericDao.getOutgoingEdgeByCriteria(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) heatParameterValue.getUniqueId(), GraphEdgeLabels.PARAMETER_IMPL, null);
397             if (getOutgoingRelation.isRight()) {
398                 log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
399                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getOutgoingRelation.right().value()));
400             }
401             Edge edge = getOutgoingRelation.left().value();
402             if (edge == null) {
403                 log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId());
404                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
405             }
406             edge.remove();
407
408             Either<HeatParameterValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(heatParameterValue, HeatParameterValueData.class);
409             if (deleteNode.isRight()) {
410                 log.debug("Failed to delete heat parameter value on graph. id = {}", heatParameterValue.getUniqueId());
411                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()));
412             }
413             return Either.left(deleteNode.left().value());
414         }
415         heatParameterValue.setValue(heatParam.getCurrentValue());
416         Either<HeatParameterValueData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterValue, HeatParameterValueData.class);
417         if (updateNode.isRight()) {
418             log.debug("Failed to update heat parameter value in graph. id = {}", heatParameterValue.getUniqueId());
419             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()));
420         }
421         return Either.left(updateNode.left().value());
422     }
423
424     public Either<HeatParameterValueData, StorageOperationStatus> createHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) {
425
426         Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph = addHeatValueToGraph(heatParam, artifactLabel, artifactId, resourceInstanceId);
427         if (addHeatValueToGraph.isRight()) {
428             log.debug("Failed to create heat parameters value on graph for artifact {}", artifactId);
429             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addHeatValueToGraph.right().value()));
430         }
431         return Either.left(addHeatValueToGraph.left().value());
432     }
433
434     public Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph(HeatParameterDefinition heatParameter, String artifactLabel, String artifactId, String resourceInstanceId) {
435
436         UniqueIdData heatEnvNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId);
437         HeatParameterValueData heatValueData = new HeatParameterValueData();
438         heatValueData.setUniqueId(UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParameter.getName()));
439         heatValueData.setValue(heatParameter.getCurrentValue());
440
441         log.debug("Before adding property to graph {}", heatValueData);
442         Either<HeatParameterValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(heatValueData, HeatParameterValueData.class);
443         log.debug("After adding property to graph {}", heatValueData);
444         if (createNodeResult.isRight()) {
445             TitanOperationStatus operationStatus = createNodeResult.right().value();
446             log.error("Failed to add heat value {} to graph. status is {}", heatValueData.getUniqueId(), operationStatus);
447             return Either.right(operationStatus);
448         }
449
450         Map<String, Object> props = new HashMap<>();
451         props.put(GraphPropertiesDictionary.NAME.getProperty(), heatParameter.getName());
452         Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(heatEnvNode, heatValueData, GraphEdgeLabels.PARAMETER_VALUE, props);
453         if (createRelResult.isRight()) {
454             TitanOperationStatus operationStatus = createRelResult.right().value();
455             log.error("Failed to associate heat value {} to heat env artifact {} in graph. status is {}", heatValueData.getUniqueId(), artifactId, operationStatus);
456             return Either.right(operationStatus);
457         }
458         UniqueIdData heatParameterNode = new UniqueIdData(NodeTypeEnum.HeatParameter, heatParameter.getUniqueId());
459         Either<GraphRelation, TitanOperationStatus> createRel2Result = titanGenericDao.createRelation(heatValueData, heatParameterNode, GraphEdgeLabels.PARAMETER_IMPL, null);
460         if (createRel2Result.isRight()) {
461             TitanOperationStatus operationStatus = createRel2Result.right().value();
462             log.error("Failed to associate heat value {} to heat parameter {} in graph. status is {}", heatValueData.getUniqueId(), heatParameter.getName(), operationStatus);
463             return Either.right(operationStatus);
464         }
465
466         return Either.left(createNodeResult.left().value());
467
468     }
469
470 }