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