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