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