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