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