4284afea0f3ffbd068a1c1263c9e2184a939c3b5
[sdc.git] /
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.F;
24 import org.janusgraph.core.JanusGraph;
25 import org.janusgraph.core.JanusGraphVertex;
26 import fj.data.Either;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.UUID;
30 import java.util.function.Supplier;
31 import org.apache.commons.lang3.tuple.ImmutablePair;
32 import org.apache.tinkerpop.gremlin.structure.Vertex;
33 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
36 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
37 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
38 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
39 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
40 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
41 import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary;
42 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
43 import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao;
44 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
46 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
47 import org.openecomp.sdc.be.model.ComponentInstance;
48 import org.openecomp.sdc.be.model.ComponentInstanceInput;
49 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
50 import org.openecomp.sdc.be.model.DataTypeDefinition;
51 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
52 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
53 import org.openecomp.sdc.be.model.operations.api.IInputsOperation;
54 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
55 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
56 import org.openecomp.sdc.be.resources.data.AttributeData;
57 import org.openecomp.sdc.be.resources.data.AttributeValueData;
58 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
59 import org.openecomp.sdc.be.resources.data.InputValueData;
60 import org.openecomp.sdc.be.resources.data.InputsData;
61 import org.openecomp.sdc.common.datastructure.Wrapper;
62 import org.openecomp.sdc.common.log.wrappers.Logger;
63 import org.springframework.beans.factory.annotation.Autowired;
64
65 @org.springframework.stereotype.Component("component-instance-operation")
66 public class ComponentInstanceOperation extends AbstractOperation {
67
68     public ComponentInstanceOperation() {
69         super();
70     }
71
72     private static final Logger log = Logger.getLogger(ComponentInstanceOperation.class.getName());
73
74     @Autowired
75     PropertyOperation propertyOperation;
76
77     @Autowired
78     private IInputsOperation inputOperation;
79
80     @Autowired
81     private ApplicationDataTypeCache dataTypeCache;
82
83     /**
84      * FOR TEST ONLY
85      *
86      * @param janusGraphGenericDao
87      */
88     public void setJanusGraphGenericDao(HealingJanusGraphGenericDao janusGraphGenericDao) {
89         this.janusGraphGenericDao = janusGraphGenericDao;
90     }
91
92     public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction) {
93
94         Either<Integer, StorageOperationStatus> result = null;
95         try {
96
97             Either<JanusGraph, JanusGraphOperationStatus> graphResult = janusGraphGenericDao.getGraph();
98             if (graphResult.isRight()) {
99                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(graphResult.right().value()));
100                 return result;
101             }
102             Either<JanusGraphVertex, JanusGraphOperationStatus> vertexService = janusGraphGenericDao
103                 .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId);
104             if (vertexService.isRight()) {
105                 log.debug("failed to fetch vertex of resource instance for id = {}", resourceInstanceId);
106                 JanusGraphOperationStatus status = vertexService.right().value();
107                 if (status == JanusGraphOperationStatus.NOT_FOUND) {
108                     status = JanusGraphOperationStatus.INVALID_ID;
109                 }
110                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexService.right().value()));
111                 return result;
112             }
113             Vertex vertex = vertexService.left().value();
114
115             VertexProperty<Object> vertexProperty = vertex.property(counterType.getProperty());
116             Integer counter = 0;
117             if (vertexProperty.isPresent()) {
118                 if (vertexProperty.value() != null) {
119                     counter = (Integer) vertexProperty.value();
120                 }
121             }
122
123             counter++;
124             vertex.property(counterType.getProperty(), counter);
125
126             result = Either.left(counter);
127             return result;
128
129         } finally {
130             if (!inTransaction) {
131                 if (result == null || result.isRight()) {
132                     log.error("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute rollback on graph.");
133                     janusGraphGenericDao.rollback();
134                 } else {
135                     log.debug("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute commit on graph.");
136                     janusGraphGenericDao.commit();
137                 }
138             }
139         }
140
141     }
142
143     private void connectAttValueDataToComponentInstanceData(Wrapper<JanusGraphOperationStatus> errorWrapper, ComponentInstanceData compIns, AttributeValueData attValueData) {
144
145         Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
146             .createRelation(compIns, attValueData, GraphEdgeLabels.ATTRIBUTE_VALUE, null);
147
148         if (createRelResult.isRight()) {
149             JanusGraphOperationStatus operationStatus = createRelResult.right().value();
150             errorWrapper.setInnerElement(operationStatus);
151             BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToComponentInstanceData",
152                     "Failed to associate resource instance " + compIns.getUniqueId() + " attribute value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
153         }
154     }
155
156     private void connectAttValueDataToAttData(Wrapper<JanusGraphOperationStatus> errorWrapper, AttributeData attData, AttributeValueData attValueData) {
157
158         Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
159             .createRelation(attValueData, attData, GraphEdgeLabels.ATTRIBUTE_IMPL, null);
160
161         if (createRelResult.isRight()) {
162             JanusGraphOperationStatus operationStatus = createRelResult.right().value();
163             BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToAttData",
164                     "Failed to associate attribute value " + attValueData.getUniqueId() + " to attribute " + attData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR);
165
166             errorWrapper.setInnerElement(operationStatus);
167         }
168     }
169
170     private void createAttributeValueDataNode(ComponentInstanceProperty attributeInstanceProperty, Integer index, Wrapper<JanusGraphOperationStatus> errorWrapper, ComponentInstanceData resourceInstanceData,
171                                               Wrapper<AttributeValueData> attValueDataWrapper) {
172         String valueUniqueUid = attributeInstanceProperty.getValueUniqueUid();
173         if (valueUniqueUid == null) {
174
175             String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceAttributeValueUid(resourceInstanceData.getUniqueId(), index);
176             AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute(attributeInstanceProperty, attValueDatauniqueId);
177
178             log.debug("Before adding attribute value to graph {}", attributeValueData);
179             Either<AttributeValueData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao
180                 .createNode(attributeValueData, AttributeValueData.class);
181             log.debug("After adding attribute value to graph {}", attributeValueData);
182
183             if (createNodeResult.isRight()) {
184                 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
185                 errorWrapper.setInnerElement(operationStatus);
186             } else {
187                 attValueDataWrapper.setInnerElement(createNodeResult.left().value());
188             }
189
190         } else {
191             BeEcompErrorManager.getInstance().logInternalFlowError("CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR);
192             errorWrapper.setInnerElement(JanusGraphOperationStatus.ALREADY_EXIST);
193         }
194     }
195
196     private AttributeValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceProperty resourceInstanceAttribute, String uniqueId) {
197         AttributeValueData attributeValueData = new AttributeValueData();
198         attributeValueData.setUniqueId(uniqueId);
199         attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
200         attributeValueData.setValue(resourceInstanceAttribute.getValue());
201         attributeValueData.setType(resourceInstanceAttribute.getType());
202         long currentTimeMillis = System.currentTimeMillis();
203         attributeValueData.setCreationTime(currentTimeMillis);
204         attributeValueData.setModificationTime(currentTimeMillis);
205         return attributeValueData;
206     }
207
208     private static final class UpdateDataContainer<SomeData, SomeValueData> {
209         final Wrapper<SomeValueData> valueDataWrapper;
210         final Wrapper<SomeData> dataWrapper;
211         final GraphEdgeLabels graphEdge;
212         final Supplier<Class<SomeData>> someDataClassGen;
213         final Supplier<Class<SomeValueData>> someValueDataClassGen;
214         final NodeTypeEnum nodeType;
215         final NodeTypeEnum nodeTypeValue;
216
217         private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) {
218             super();
219             this.valueDataWrapper = new Wrapper<>();
220             this.dataWrapper = new Wrapper<>();
221             this.graphEdge = graphEdge;
222             this.someDataClassGen = someDataClassGen;
223             this.someValueDataClassGen = someValueDataClassGen;
224             this.nodeType = nodeType;
225             this.nodeTypeValue = nodeTypeValue;
226         }
227
228         public Wrapper<SomeValueData> getValueDataWrapper() {
229             return valueDataWrapper;
230         }
231
232         public Wrapper<SomeData> getDataWrapper() {
233             return dataWrapper;
234         }
235
236         public GraphEdgeLabels getGraphEdge() {
237             return graphEdge;
238         }
239
240         public Supplier<Class<SomeData>> getSomeDataClassGen() {
241             return someDataClassGen;
242         }
243
244         public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() {
245             return someValueDataClassGen;
246         }
247
248         public NodeTypeEnum getNodeType() {
249             return nodeType;
250         }
251
252         public NodeTypeEnum getNodeTypeValue() {
253             return nodeTypeValue;
254         }
255     }
256
257     /**
258      * update value of attribute on resource instance
259      *
260      * @param resourceInstanceAttribute
261      * @param resourceInstanceId
262      * @return
263      */
264     private Either<AttributeValueData, JanusGraphOperationStatus> updateAttributeOfResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId) {
265         Wrapper<JanusGraphOperationStatus> errorWrapper = new Wrapper<>();
266         UpdateDataContainer<AttributeData, AttributeValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.ATTRIBUTE_IMPL, (() -> AttributeData.class), (() -> AttributeValueData.class), NodeTypeEnum.Attribute,
267                 NodeTypeEnum.AttributeValue);
268         preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceAttribute, resourceInstanceId, errorWrapper);
269         if (errorWrapper.isEmpty()) {
270             AttributeValueData attributeValueData = updateDataContainer.getValueDataWrapper().getInnerElement();
271             attributeValueData.setHidden(resourceInstanceAttribute.isHidden());
272             attributeValueData.setValue(resourceInstanceAttribute.getValue());
273
274             return janusGraphGenericDao.updateNode(
275                 attributeValueData, AttributeValueData.class
276             );
277         } else {
278             return Either.right(errorWrapper.getInnerElement());
279         }
280     }
281
282     private Either<AttributeValueData, JanusGraphOperationStatus> addAttributeToResourceInstance(ComponentInstanceProperty attributeInstanceProperty, String resourceInstanceId, Integer index) {
283         Wrapper<JanusGraphOperationStatus> errorWrapper = new Wrapper<>();
284         Wrapper<ComponentInstanceData> compInsWrapper = new Wrapper<>();
285         Wrapper<AttributeData> attDataWrapper = new Wrapper<>();
286         Wrapper<AttributeValueData> attValueDataWrapper = new Wrapper<>();
287
288         // Verify RI Exist
289         validateRIExist(resourceInstanceId, compInsWrapper, errorWrapper);
290
291         if (errorWrapper.isEmpty()) {
292             // Verify Attribute Exist
293             validateElementExistInGraph(attributeInstanceProperty.getUniqueId(), NodeTypeEnum.Attribute, () -> AttributeData.class, attDataWrapper, errorWrapper);
294         }
295         if (errorWrapper.isEmpty()) {
296             // Create AttributeValueData that is connected to RI
297             createAttributeValueDataNode(attributeInstanceProperty, index, errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper);
298         }
299         if (errorWrapper.isEmpty()) {
300             // Connect AttributeValueData (Att on RI) to AttData (Att on
301             // Resource)
302             connectAttValueDataToAttData(errorWrapper, attDataWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
303         }
304         if (errorWrapper.isEmpty()) {
305             // Connect AttributeValueData to RI
306             connectAttValueDataToComponentInstanceData(errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper.getInnerElement());
307         }
308
309         if (errorWrapper.isEmpty()) {
310             return Either.left(attValueDataWrapper.getInnerElement());
311         } else {
312             return Either.right(errorWrapper.getInnerElement());
313         }
314
315     }
316
317     private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
318             String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
319
320         if (errorWrapper.isEmpty()) {
321             // Verify VFC instance Exist
322             validateRIExist(resourceInstanceId, errorWrapper);
323         }
324
325         if (errorWrapper.isEmpty()) {
326             // Example: Verify Property connected to VFC exist
327             validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
328         }
329
330         if (errorWrapper.isEmpty()) {
331             // Example: Verify PropertyValue connected to VFC Instance exist
332             validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper);
333         }
334
335         if (errorWrapper.isEmpty()) {
336             // Example: Verify PropertyValue connected Property
337             validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper);
338         }
339     }
340
341     private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty,
342             Wrapper<JanusGraphOperationStatus> errorWrapper) {
343         Either<ImmutablePair<SomeData, GraphEdge>, JanusGraphOperationStatus> child = janusGraphGenericDao
344             .getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(),
345                 updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get());
346
347         if (child.isRight()) {
348             JanusGraphOperationStatus status = child.right().value();
349             if (status == JanusGraphOperationStatus.NOT_FOUND) {
350                 status = JanusGraphOperationStatus.INVALID_ID;
351             }
352             errorWrapper.setInnerElement(status);
353
354         } else {
355             updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left);
356         }
357     }
358
359     private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
360             IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<JanusGraphOperationStatus> errorWrapper) {
361         String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid();
362         if (valueUniqueUid == null) {
363             errorWrapper.setInnerElement(JanusGraphOperationStatus.INVALID_ID);
364         } else {
365             Either<SomeValueData, JanusGraphOperationStatus> findPropertyValueRes = janusGraphGenericDao
366                 .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get());
367             if (findPropertyValueRes.isRight()) {
368                 JanusGraphOperationStatus status = findPropertyValueRes.right().value();
369                 if (status == JanusGraphOperationStatus.NOT_FOUND) {
370                     status = JanusGraphOperationStatus.INVALID_ID;
371                 }
372                 errorWrapper.setInnerElement(status);
373             } else {
374                 updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value());
375             }
376         }
377     }
378
379     private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer,
380             IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<JanusGraphOperationStatus> errorWrapper) {
381         String uniqueId = resourceInstanceElementConnected.getUniqueId();
382         Either<SomeData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
383             .getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get());
384
385         if (findPropertyDefRes.isRight()) {
386             JanusGraphOperationStatus status = findPropertyDefRes.right().value();
387             errorWrapper.setInnerElement(status);
388         }
389     }
390
391     private void validateRIExist(String resourceInstanceId, Wrapper<JanusGraphOperationStatus> errorWrapper) {
392         validateRIExist(resourceInstanceId, null, errorWrapper);
393     }
394
395     private void validateRIExist(String resourceInstanceId, Wrapper<ComponentInstanceData> compInsDataWrapper, Wrapper<JanusGraphOperationStatus> errorWrapper) {
396         validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.ResourceInstance, () -> ComponentInstanceData.class, compInsDataWrapper, errorWrapper);
397     }
398
399     public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper,
400             Wrapper<JanusGraphOperationStatus> errorWrapper) {
401         Either<ElementData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
402             .getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get());
403         if (findResInstanceRes.isRight()) {
404             JanusGraphOperationStatus status = findResInstanceRes.right().value();
405             if (status == JanusGraphOperationStatus.NOT_FOUND) {
406                 status = JanusGraphOperationStatus.INVALID_ID;
407             }
408             errorWrapper.setInnerElement(status);
409         } else {
410             if (elementDataWrapper != null) {
411                 elementDataWrapper.setInnerElement(findResInstanceRes.left().value());
412             }
413         }
414     }
415
416     /**
417      * add property to resource instance
418      *
419      * @param resourceInstanceId
420      * @param index
421      * @return
422      */
423     private Either<InputValueData, JanusGraphOperationStatus> addInputToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index) {
424
425         Either<ComponentInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao
426             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class);
427
428         if (findResInstanceRes.isRight()) {
429             JanusGraphOperationStatus status = findResInstanceRes.right().value();
430             if (status == JanusGraphOperationStatus.NOT_FOUND) {
431                 status = JanusGraphOperationStatus.INVALID_ID;
432             }
433             return Either.right(status);
434         }
435
436         String propertyId = resourceInstanceInput.getUniqueId();
437         Either<InputsData, JanusGraphOperationStatus> findPropertyDefRes = janusGraphGenericDao
438             .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), propertyId, InputsData.class);
439
440         if (findPropertyDefRes.isRight()) {
441             JanusGraphOperationStatus status = findPropertyDefRes.right().value();
442             if (status == JanusGraphOperationStatus.NOT_FOUND) {
443                 status = JanusGraphOperationStatus.INVALID_ID;
444             }
445             return Either.right(status);
446         }
447
448         String valueUniqueUid = resourceInstanceInput.getValueUniqueUid();
449         if (valueUniqueUid == null) {
450
451             InputsData propertyData = findPropertyDefRes.left().value();
452
453             ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value();
454
455             ImmutablePair<JanusGraphOperationStatus, String> isInputValueExists = inputOperation.findInputValue(resourceInstanceId, propertyId);
456             if (isInputValueExists.getLeft() == JanusGraphOperationStatus.ALREADY_EXIST) {
457                 log.debug("The property {} already added to the resource instance {}", propertyId, resourceInstanceId);
458                 resourceInstanceInput.setValueUniqueUid(isInputValueExists.getRight());
459             }
460
461             if (isInputValueExists.getLeft() != JanusGraphOperationStatus.NOT_FOUND) {
462                 log.debug("After finding input value of {} on componenet instance {}", propertyId, resourceInstanceId);
463                 return Either.right(isInputValueExists.getLeft());
464             }
465
466             String innerType = null;
467
468             PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition();
469             String propertyType = propDataDef.getType();
470             String value = resourceInstanceInput.getValue();
471             ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
472
473             if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
474                 SchemaDefinition def = propDataDef.getSchema();
475                 if (def == null) {
476                     log.debug("Schema doesn't exists for property of type {}", type);
477                     return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
478                 }
479                 PropertyDataDefinition propDef = def.getProperty();
480                 if (propDef == null) {
481                     log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
482                     return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
483                 }
484                 innerType = propDef.getType();
485             }
486
487             log.debug("Before validateAndUpdatePropertyValue");
488             Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = dataTypeCache.getAll();
489             if (allDataTypes.isRight()) {
490                 JanusGraphOperationStatus status = allDataTypes.right().value();
491                 BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
492                 return Either.right(status);
493             }
494
495             String uniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData.getUniqueId(), index);
496             InputValueData propertyValueData = new InputValueData();
497             propertyValueData.setUniqueId(uniqueId);
498             propertyValueData.setValue(value);
499
500             log.debug("Before validateAndUpdateRules");
501             ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceInput.getRules(), innerType, allDataTypes.left().value(), true);
502             log.debug("After validateAndUpdateRules. pair = {} ", pair);
503             if (pair.getRight() != null && !pair.getRight()) {
504                 BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceInput.getName(), propertyType);
505                 return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT);
506             }
507             log.debug("Before adding property value to graph {}", propertyValueData);
508             Either<InputValueData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao
509                 .createNode(propertyValueData, InputValueData.class);
510             log.debug("After adding property value to graph {}", propertyValueData);
511
512             if (createNodeResult.isRight()) {
513                 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
514                 return Either.right(operationStatus);
515             }
516
517             Either<GraphRelation, JanusGraphOperationStatus> createRelResult = janusGraphGenericDao
518                 .createRelation(propertyValueData, propertyData, GraphEdgeLabels.INPUT_IMPL, null);
519
520             if (createRelResult.isRight()) {
521                 JanusGraphOperationStatus operationStatus = createRelResult.right().value();
522                 log.error("Failed to associate property value {} to property {} in graph. status is {}", uniqueId, propertyId, operationStatus);
523                 return Either.right(operationStatus);
524             }
525
526             Map<String, Object> properties1 = new HashMap<>();
527
528             properties1.put(GraphEdgePropertiesDictionary.NAME.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getName());
529             properties1.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getUniqueId());
530
531             createRelResult = janusGraphGenericDao
532                 .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.INPUT_VALUE, properties1);
533
534             if (createRelResult.isRight()) {
535                 JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
536                 log.error("Failed to associate resource instance {} property value {} in graph. status is {}", resourceInstanceId, uniqueId, operationStatus);
537                 return Either.right(operationStatus);
538
539             }
540
541             return Either.left(createNodeResult.left().value());
542         } else {
543             log.error("property value already exists.");
544             return Either.right(JanusGraphOperationStatus.ALREADY_EXIST);
545         }
546
547     }
548
549     public Either<ComponentInstanceProperty, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction) {
550         Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
551
552         try {
553
554             Either<AttributeValueData, JanusGraphOperationStatus> eitherStatus = this.addAttributeToResourceInstance(resourceInstanceAttribute, resourceInstanceId, index);
555
556             if (eitherStatus.isRight()) {
557                 log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherStatus.right().value().name());
558                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
559                 return result;
560             } else {
561                 AttributeValueData attributeValueData = eitherStatus.left().value();
562
563                 ComponentInstanceProperty attributeValueResult = buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
564                 log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
565
566                 result = Either.left(attributeValueResult);
567                 return result;
568             }
569         }
570
571         finally {
572             handleTransactionCommitRollback(inTransaction, result);
573         }
574     }
575
576     private ComponentInstanceProperty buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceProperty resourceInstanceAttribute) {
577         Boolean hidden = attributeValueData.isHidden();
578         String uid = attributeValueData.getUniqueId();
579         return new ComponentInstanceProperty(hidden, resourceInstanceAttribute, uid);
580     }
581
582     public Either<ComponentInstanceProperty, StorageOperationStatus> updateAttributeValueInResourceInstance(
583         ComponentInstanceProperty resourceInstanceAttribute,
584         String resourceInstanceId,
585         boolean inTransaction
586     ) {
587         //TODO This null could bubble up. Shouldn't we set a default value (such as Either.left(StorageOperationStatus.GENERAL_ERROR)) ?
588         Either<ComponentInstanceProperty, StorageOperationStatus> result = null;
589         try {
590             result = updateAttributeOfResourceInstance(resourceInstanceAttribute, resourceInstanceId)
591                 .bimap(
592                     buildResourceInstanceAttribute(resourceInstanceAttribute),
593                     handleFailedAttributeAdditionError(resourceInstanceAttribute, resourceInstanceId));
594         } finally {
595             handleTransactionCommitRollback(inTransaction, result);
596         }
597         return result;
598     }
599
600     private F<JanusGraphOperationStatus, StorageOperationStatus> handleFailedAttributeAdditionError(
601         ComponentInstanceProperty resourceInstanceAttribute, String resourceInstanceId) {
602         return status -> {
603             log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}",
604                 resourceInstanceAttribute, resourceInstanceId, status.name());
605             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
606         };
607     }
608
609     private F<AttributeValueData, ComponentInstanceProperty> buildResourceInstanceAttribute(
610         ComponentInstanceProperty resourceInstanceAttribute) {
611         return attributeValueData -> {
612             ComponentInstanceProperty attributeValueResult =
613                 buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute);
614             log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult);
615             return attributeValueResult;
616         };
617     }
618
619     public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index, boolean inTransaction) {
620
621         /// #RULES SUPPORT
622         /// Ignore rules received from client till support
623         resourceInstanceInput.setRules(null);
624         ///
625         ///
626
627         Either<ComponentInstanceInput, StorageOperationStatus> result = null;
628
629         try {
630
631             Either<InputValueData, JanusGraphOperationStatus> eitherStatus = addInputToResourceInstance(resourceInstanceInput, resourceInstanceId, index);
632
633             if (eitherStatus.isRight()) {
634                 log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", resourceInstanceInput, resourceInstanceId, eitherStatus.right().value().name());
635                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(eitherStatus.right().value()));
636                 return result;
637             } else {
638                 InputValueData propertyValueData = eitherStatus.left().value();
639
640                 ComponentInstanceInput propertyValueResult = inputOperation.buildResourceInstanceInput(propertyValueData, resourceInstanceInput);
641                 log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult);
642
643                 Either<String, JanusGraphOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceInput.getPath(), resourceInstanceInput.getUniqueId(), resourceInstanceInput.getDefaultValue());
644                 if (findDefaultValue.isRight()) {
645                     result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findDefaultValue.right().value()));
646                     return result;
647                 }
648                 String defaultValue = findDefaultValue.left().value();
649                 propertyValueResult.setDefaultValue(defaultValue);
650                 log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
651
652                 result = Either.left(propertyValueResult);
653                 return result;
654             }
655         }
656
657         finally {
658             if (!inTransaction) {
659                 if (result == null || result.isRight()) {
660                     log.error("Going to execute rollback on graph.");
661                     janusGraphGenericDao.rollback();
662                 } else {
663                     log.debug("Going to execute commit on graph.");
664                     janusGraphGenericDao.commit();
665                 }
666             }
667         }
668
669     }
670
671     public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b) {
672         return null;
673     }
674
675     public StorageOperationStatus updateCustomizationUUID(String componentInstanceId) {
676         Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = janusGraphGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), componentInstanceId);
677         if (vertexByProperty.isRight()) {
678             log.debug("Failed to fetch component instance by id {} error {}", componentInstanceId, vertexByProperty.right().value());
679             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexByProperty.right().value());
680         }
681         UUID uuid = UUID.randomUUID();
682         JanusGraphVertex ciVertex = vertexByProperty.left().value();
683         ciVertex.property(GraphPropertiesDictionary.CUSTOMIZATION_UUID.getProperty(), uuid.toString());
684
685         return StorageOperationStatus.OK;
686     }
687
688     public Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction) {
689
690         log.debug("Going to update modification time of component instance {}. ", componentInstance.getName());
691         Either<ComponentInstanceData, StorageOperationStatus> result = null;
692         try{
693             ComponentInstanceData componentData = new ComponentInstanceData(componentInstance, componentInstance.getGroupInstances().size());
694             componentData.getComponentInstDataDefinition().setModificationTime(modificationTime);
695             componentData.getComponentInstDataDefinition().setCustomizationUUID(UUID.randomUUID().toString());
696             Either<ComponentInstanceData, JanusGraphOperationStatus> updateNode = janusGraphGenericDao
697                 .updateNode(componentData, ComponentInstanceData.class);
698             if (updateNode.isRight()) {
699                 log.error("Failed to update resource {}. status is {}", componentInstance.getUniqueId(), updateNode.right().value());
700                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateNode.right().value()));
701             }else{
702                 result = Either.left(updateNode.left().value());
703             }
704         }catch(Exception e){
705             log.error("Exception occured during  update modification date of compomemt instance{}. The message is {}. ", componentInstance.getName(), e.getMessage(), e);
706             result = Either.right(StorageOperationStatus.GENERAL_ERROR);
707         }finally {
708             if(!inTransaction){
709                 if (result == null || result.isRight()) {
710                     log.error("Going to execute rollback on graph.");
711                     janusGraphGenericDao.rollback();
712                 } else {
713                     log.debug("Going to execute commit on graph.");
714                     janusGraphGenericDao.commit();
715                 }
716             }
717         }
718         return result;
719     }
720 }