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