new unit tests for sdc-dao
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsontitan / operations / NodeTemplateOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.jsontitan.operations;
22
23 import java.util.ArrayList;
24 import java.util.EnumMap;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.UUID;
34 import java.util.function.BiConsumer;
35 import java.util.function.BiPredicate;
36 import java.util.stream.Collectors;
37
38 import org.apache.commons.collections.CollectionUtils;
39 import org.apache.commons.collections.MapUtils;
40 import org.apache.commons.lang.StringUtils;
41 import org.apache.commons.lang3.tuple.ImmutablePair;
42 import org.apache.commons.lang3.tuple.Pair;
43 import org.openecomp.sdc.be.config.BeEcompErrorManager;
44 import org.openecomp.sdc.be.config.ConfigurationManager;
45 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
46 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
47 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
48 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
49 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
50 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
58 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
59 import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
60 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
61 import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
62 import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
68 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
69 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
70 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
71 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
72 import org.openecomp.sdc.be.model.ArtifactDefinition;
73 import org.openecomp.sdc.be.model.CapabilityDefinition;
74 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
75 import org.openecomp.sdc.be.model.Component;
76 import org.openecomp.sdc.be.model.ComponentInstance;
77 import org.openecomp.sdc.be.model.ComponentInstanceInput;
78 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
79 import org.openecomp.sdc.be.model.ComponentParametersView;
80 import org.openecomp.sdc.be.model.GroupDefinition;
81 import org.openecomp.sdc.be.model.GroupInstance;
82 import org.openecomp.sdc.be.model.RelationshipImpl;
83 import org.openecomp.sdc.be.model.RelationshipInfo;
84 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
85 import org.openecomp.sdc.be.model.RequirementDefinition;
86 import org.openecomp.sdc.be.model.Resource;
87 import org.openecomp.sdc.be.model.User;
88 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
89 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
90 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
91 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
92 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
93 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
94 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
95 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
96 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
97 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
98 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
99 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
100 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
101 import org.openecomp.sdc.common.util.ValidationUtils;
102 import org.slf4j.Logger;
103 import org.slf4j.LoggerFactory;
104
105 import fj.data.Either;
106
107 @org.springframework.stereotype.Component("node-template-operation")
108 public class NodeTemplateOperation extends BaseOperation {
109         private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
110         private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
111         private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
112         public static final String HEAT_ENV_NAME = "heatEnv";
113         public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
114         public static final String HEAT_ENV_SUFFIX = "env";
115         private static Integer defaultHeatTimeout;
116         public static final Integer NON_HEAT_TIMEOUT = 0;
117
118         private static Logger logger = LoggerFactory.getLogger(NodeTemplateOperation.class.getName());
119
120         public NodeTemplateOperation() {
121                 defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes();
122                 if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) {
123                         defaultHeatTimeout = 60;
124                 }
125         }
126
127         public static Integer getDefaultHeatTimeout() {
128                 return defaultHeatTimeout;
129         }
130
131         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, String instanceNumberSuffix, ComponentInstance componentInstance,
132                         boolean allowDeleted, User user) {
133
134                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
135                 Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceRes = null;
136                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to create component instance {} in component {}", componentInstance, container.getUniqueId());
137                 ComponentInstanceDataDefinition componentInstanceData = null;
138                 Either<String, StorageOperationStatus> newInstanceNameRes = null;
139
140                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseJson);
141                 if (metadataVertex.isRight()) {
142                         TitanOperationStatus status = metadataVertex.right().value();
143                         if (status == TitanOperationStatus.NOT_FOUND) {
144                                 status = TitanOperationStatus.INVALID_ID;
145                         }
146                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
147                 }
148
149                 if (result == null) {
150
151                         newInstanceNameRes = buildValidateInstanceName(container, originToscaElement, componentInstance, instanceNumberSuffix);
152                         if (newInstanceNameRes.isRight()) {
153                                 result = Either.right(newInstanceNameRes.right().value());
154                         }
155                 }
156                 if (result == null) {
157                         componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), newInstanceNameRes.left().value(), true, originToscaElement);
158
159                         addComponentInstanceRes = addComponentInstanceToTopologyTemplate(container, originToscaElement, componentInstanceData, metadataVertex.left().value(), allowDeleted, user);
160
161                         if (addComponentInstanceRes.isRight()) {
162                                 StorageOperationStatus status = addComponentInstanceRes.right().value();
163                                 if (status == StorageOperationStatus.NOT_FOUND) {
164                                         status = StorageOperationStatus.INVALID_ID;
165                                 }
166                                 result = Either.right(status);
167                         }
168                         if(componentInstance.getOriginType()  == OriginTypeEnum.ServiceProxy){
169                                 TopologyTemplate updatedContainer = addComponentInstanceRes.left().value();
170                                 result = addServerCapAndReqToProxyServerInstance(
171                                                 updatedContainer, componentInstance, componentInstanceData);
172                                 
173
174                         
175                         }
176                 }
177                 if (result == null) {
178                         result = Either.left(new ImmutablePair<>(addComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
179                 }
180                 return result;
181         }
182
183         private Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addServerCapAndReqToProxyServerInstance(TopologyTemplate updatedContainer, ComponentInstance componentInstance,
184                         
185                         ComponentInstanceDataDefinition componentInstanceData) {
186                 
187                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result;
188                 
189         
190                 Map<String, MapListCapabiltyDataDefinition> calcCap = updatedContainer.getCalculatedCapabilities();
191                 Map<String, MapListRequirementDataDefinition>  calcReg = updatedContainer.getCalculatedRequirements();
192                 Map<String, MapCapabiltyProperty> calcCapProp = updatedContainer.getCalculatedCapabilitiesProperties();
193                 
194                 
195                 Map<String, List<CapabilityDefinition>> additionalCap = componentInstance.getCapabilities();
196                 Map<String, List<RequirementDefinition>> additionalReq = componentInstance.getRequirements();
197                 
198                 MapListCapabiltyDataDefinition  allCalculatedCap = calcCap==null ||!calcCap.containsKey(componentInstanceData.getUniqueId())?new MapListCapabiltyDataDefinition() :calcCap.get(componentInstanceData.getUniqueId());
199                 /********capability****************************/
200                 StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceData.getUniqueId());
201                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
202                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
203                         return Either.right(status);
204                 }
205                 
206                 if(additionalCap != null && !additionalCap.isEmpty()){
207                         
208                         Map<String, ListCapabilityDataDefinition> serverCap = additionalCap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ListCapabilityDataDefinition(en.getValue().stream().map(iCap -> new CapabilityDataDefinition(iCap)).collect(Collectors.toList()))));
209                         
210                         serverCap.entrySet().forEach(entryPerType -> {
211                                         entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
212                                                 cap.addToPath(componentInstance.getUniqueId());                                                 
213                                                 allCalculatedCap.add(entryPerType.getKey(), cap);
214                                         });
215                                 });
216                         
217                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
218                                         componentInstance.getUniqueId());
219                         
220                         /********capability property****************************/
221                         status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceData.getUniqueId());
222                         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
223                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
224                                 return Either.right(status);
225                         }
226                         
227                         
228                         MapCapabiltyProperty    allCalculatedCapProp = calcCapProp==null ||!calcCapProp.containsKey(componentInstanceData.getUniqueId())?new MapCapabiltyProperty() :calcCapProp.get(componentInstanceData.getUniqueId());
229                         
230
231                         additionalCap.forEach(new BiConsumer<String, List<CapabilityDefinition>>() {
232                                 @Override
233                                 public void accept(String s, List<CapabilityDefinition> caps) {
234
235                                         if (caps != null && !caps.isEmpty()) {
236
237                                                 MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
238
239                                                 for (CapabilityDefinition cap : caps) {
240                                                         List<ComponentInstanceProperty> capPrps = cap.getProperties();
241                                                         if (capPrps != null) {
242
243                                                                 for (ComponentInstanceProperty cip : capPrps) {
244                                                                         dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
245                                                                 }
246                                                         
247
248                                                                 StringBuffer sb = new StringBuffer(componentInstance.getUniqueId());
249                                                                 sb.append(ModelConverter.CAP_PROP_DELIM);
250                                                                 
251                                                                 sb.append(cap.getOwnerId());
252                                                                 
253                                                                 sb.append(ModelConverter.CAP_PROP_DELIM).append(s).append(ModelConverter.CAP_PROP_DELIM).append(cap.getName());
254                                                                 allCalculatedCapProp.put(sb.toString(), dataToCreate);
255                                                         }
256                                                 }
257
258                                         }
259
260                                 }
261                         });
262                         
263                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, allCalculatedCapProp,
264                                         componentInstance.getUniqueId());
265                 }
266                 
267                 /********Requirements property****************************/
268                 if(additionalReq != null && !additionalReq.isEmpty()){
269                 
270                         MapListRequirementDataDefinition        allCalculatedReq = calcReg==null ||!calcReg.containsKey(componentInstanceData.getUniqueId())?new MapListRequirementDataDefinition() :calcReg.get(componentInstanceData.getUniqueId());
271                         status = deleteToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceData.getUniqueId());
272                         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
273                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated Requirements for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status);
274                                 return Either.right(status);
275                         }
276                         
277                         Map<String, ListRequirementDataDefinition> serverReq = additionalReq.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, en -> new ListRequirementDataDefinition(en.getValue().stream().map(iCap -> new RequirementDataDefinition(iCap)).collect(Collectors.toList()))));
278                                 
279                         serverReq.entrySet().forEach(entryPerType -> {
280                                         entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
281                                                 cap.addToPath(componentInstance.getUniqueId());                                                 
282                                                 allCalculatedReq.add(entryPerType.getKey(), cap);
283                                         });
284                                 });
285                         
286                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
287                                         componentInstance.getUniqueId());
288                 
289                 }
290
291
292                 Either<ToscaElement, StorageOperationStatus> updatedComponentInstanceRes = topologyTemplateOperation.getToscaElement(updatedContainer.getUniqueId());
293                 if (updatedComponentInstanceRes.isRight()) {
294                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", updatedContainer.getName(), componentInstance.getName());
295                         result = Either.right(updatedComponentInstanceRes.right().value());
296                 }
297                 result = Either.left(new ImmutablePair<>((TopologyTemplate)updatedComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
298                 return result;
299         }
300         
301
302         private Either<String, StorageOperationStatus> buildValidateInstanceName(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance, String instanceNumberSuffix) {
303
304                 Either<String, StorageOperationStatus> result = null;
305                 String instanceName = componentInstance.getName();
306                 if (StringUtils.isEmpty(instanceName) || instanceName.equalsIgnoreCase(originToscaElement.getName()) || componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
307                         instanceName = buildComponentInstanceName(instanceNumberSuffix, instanceName);
308                 } else if (!isUniqueInstanceName(container, componentInstance.getName())) {
309                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create component instance with name {} on component container {}. The instance with the same name already exists. ", componentInstance.getName(), container.getName());
310                         result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
311                 }
312                 if (result == null) {
313                         result = Either.left(instanceName);
314                 }
315                 return result;
316         }
317
318         public Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex metadataVertex,
319                         boolean allowDeleted, User user) {
320
321                 Either<TopologyTemplate, StorageOperationStatus> result = null;
322                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
323                 String containerComponentId = container.getUniqueId();
324                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to create component instance {} in component {}", componentInstance, containerComponentId);
325                 String instOriginComponentId = componentInstance.getComponentUid();
326                 Either<GraphVertex, TitanOperationStatus> updateElement = null;
327
328                 Boolean isDeleted = (Boolean) originToscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED);
329
330                 if (!allowDeleted && (isDeleted != null) && isDeleted) {
331                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance", instOriginComponentId);
332                         result = Either.right(StorageOperationStatus.INVALID_ID);
333                 }
334                 if (result == null) {
335                         container.addComponentInstance(componentInstance);
336                         metadataVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
337                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex, container, JsonParseFlagEnum.ParseAll);
338                         updateElement = titanDao.updateVertex(metadataVertex);
339                         if (updateElement.isRight()) {
340                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
341                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
342                         }
343                 }
344                 if (result == null) {
345                         Either<GraphVertex, StorageOperationStatus> addToscaDataRes = addComponentInstanceToscaDataToContainerComponent(originToscaElement, componentInstance, updateElement.left().value(), user);
346                         if (addToscaDataRes.isRight()) {
347                                 result = Either.right(addToscaDataRes.right().value());
348                         }
349                 }
350
351                 if (result == null) {
352                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
353                         if (updateContainerComponentRes.isRight()) {
354                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
355                                 result = Either.right(updateContainerComponentRes.right().value());
356                         }
357                 }
358                 if (result == null) {
359                         result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
360                 }
361                 return result;
362         }
363
364         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance) {
365
366                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
367                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
368
369                 String containerComponentId = container.getUniqueId();
370                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstance, containerComponentId);
371                 ComponentInstanceDataDefinition componentInstanceData = null;
372
373                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
374                 if (metadataVertex.isRight()) {
375                         TitanOperationStatus status = metadataVertex.right().value();
376                         if (status == TitanOperationStatus.NOT_FOUND) {
377                                 status = TitanOperationStatus.INVALID_ID;
378                         }
379                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
380                 }
381                 if (result == null) {
382                         componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), componentInstance.getName(), false, originToscaElement);
383                         container.addComponentInstance(componentInstanceData);
384                         metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
385                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
386                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
387                         if (updateElement.isRight()) {
388                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
389                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
390                         }
391                 }
392                 if (result == null) {
393                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
394                         if (updateContainerComponentRes.isRight()) {
395                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", container.getName(), componentInstance.getName());
396                                 result = Either.right(updateContainerComponentRes.right().value());
397                         }
398                 }
399                 if (result == null) {
400                         result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceData.getUniqueId()));
401                 }
402                 return result;
403         }
404
405         public Either<TopologyTemplate, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ComponentParametersView filter) {
406
407                 Either<TopologyTemplate, StorageOperationStatus> result = null;
408                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
409
410                 String containerComponentId = container.getUniqueId();
411                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata  of container component {}", containerComponentId);
412
413                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
414                 if (metadataVertex.isRight()) {
415                         TitanOperationStatus status = metadataVertex.right().value();
416                         if (status == TitanOperationStatus.NOT_FOUND) {
417                                 status = TitanOperationStatus.INVALID_ID;
418                         }
419                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
420                 }
421                 if (result == null) {
422                         metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
423                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
424                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
425                         if (updateElement.isRight()) {
426                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {}. ", container.getName());
427                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
428                         }
429                 }
430                 if (result == null) {
431                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId, filter);
432                         if (updateContainerComponentRes.isRight()) {
433                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {}. ", container.getName());
434                                 result = Either.right(updateContainerComponentRes.right().value());
435                         }
436                 }
437                 if (result == null) {
438                         result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
439                 }
440                 return result;
441         }
442
443         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(TopologyTemplate container, String componentInstanceId) {
444
445                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
446                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
447
448                 String containerComponentId = container.getUniqueId();
449                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstanceId, containerComponentId);
450
451                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
452                 if (metadataVertex.isRight()) {
453                         TitanOperationStatus status = metadataVertex.right().value();
454                         if (status == TitanOperationStatus.NOT_FOUND) {
455                                 status = TitanOperationStatus.INVALID_ID;
456                         }
457                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
458                 }
459                 GraphVertex containerV = null;
460                 if (result == null) {
461                         container.getComponentInstances().remove(componentInstanceId);
462                         containerV = metadataVertex.left().value();
463                         StorageOperationStatus status = removeRelationsOfInstance(container, componentInstanceId, containerV);
464                         if (status != StorageOperationStatus.OK) {
465                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete relation for component instance {} in container. error {}", componentInstanceId, container.getUniqueId(), status);
466                                 result = Either.right(status);
467                         }
468
469                         containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
470                         topologyTemplateOperation.fillToscaElementVertexData(containerV, container, JsonParseFlagEnum.ParseAll);
471                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
472                         if (updateElement.isRight()) {
473                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstanceId);
474                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
475                         }
476                 }
477                 if (result == null) {
478                         StorageOperationStatus status = deleteComponentInstanceToscaDataFromContainerComponent(containerV, componentInstanceId);
479                         if (status != StorageOperationStatus.OK) {
480                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete data  for instance {} in container {}. error {] ", componentInstanceId, container.getUniqueId(), status);
481                                 return Either.right(status);
482                         }
483                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
484                         if (updateContainerComponentRes.isRight()) {
485                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} after deleting the component instance {}. ", container.getName(), componentInstanceId);
486                                 result = Either.right(updateContainerComponentRes.right().value());
487                         }
488                 }
489                 if (result == null) {
490                         result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceId));
491                 }
492                 return result;
493         }
494
495         private StorageOperationStatus removeRelationsOfInstance(TopologyTemplate container, String ciToRemove, GraphVertex containerV) {
496                 CompositionDataDefinition composition = container.getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue());
497                 if (composition != null) {
498                         Map<String, RelationshipInstDataDefinition> relations = composition.getRelations();
499                         if (MapUtils.isNotEmpty(relations)) {
500                                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
501                                 if (capResult.isRight()) {
502                                         return capResult.right().value();
503
504                                 }
505                                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
506
507                                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
508                                 if (capFullResult.isRight()) {
509                                         return capFullResult.right().value();
510
511                                 }
512                                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
513
514                                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
515                                 if (reqResult.isRight()) {
516                                         return reqResult.right().value();
517                                 }
518                                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
519
520                                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
521                                 if (reqResult.isRight()) {
522                                         return reqResult.right().value();
523                                 }
524                                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
525
526                                 Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
527                                 while (iterator.hasNext()) {
528                                         Entry<String, RelationshipInstDataDefinition> relation = iterator.next();
529                                         RelationshipInstDataDefinition relationToDelete = relation.getValue();
530                                         if (relationToDelete.getFromId().equals(ciToRemove) || relationToDelete.getToId().equals(ciToRemove)) {
531                                                 iterator.remove();
532                                                 if (relationToDelete.getFromId().equals(ciToRemove)) {
533                                                         updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, ciToRemove, relationToDelete, null);
534                                                         updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, relationToDelete.getToId(), relationToDelete, null);
535                                                 }
536                                                 if (relationToDelete.getToId().equals(ciToRemove)) {
537                                                         updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, relationToDelete.getFromId(), relationToDelete, null);
538                                                         updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, ciToRemove, relationToDelete, null);
539                                                 }
540                                         }
541                                 }
542                                 return updateAllAndCalculatedCapReqOnGraph(container.getUniqueId(), containerV, capResult, capFullResult, reqResult, reqFullResult);
543                         }
544                 }
545                 return StorageOperationStatus.OK;
546         }
547
548         private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
549                 StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
550                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
551                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
552                         return status;
553                 }
554                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceId);
555                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
556                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
557                         return status;
558                 }
559                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
560                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
561                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
562                         return status;
563                 }
564                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
565                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
566                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
567                         return status;
568                 }
569                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
570                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
571                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
572                         return status;
573                 }
574                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, componentInstanceId);
575                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
576                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove attributes for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
577                         return status;
578                 }
579                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, componentInstanceId);
580                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
581                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
582                         return status;
583                 }
584                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, componentInstanceId);
585                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
586                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
587                         return status;
588                 }
589                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, componentInstanceId);
590                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
591                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
592                         return status;
593                 }
594                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
595                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
596                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance deployment artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
597                         return status;
598                 }
599                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS, componentInstanceId);
600                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
601                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
602                         return status;
603                 }
604                 return StorageOperationStatus.OK;
605         }
606
607         protected Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user) {
608
609                 Either<GraphVertex, StorageOperationStatus> result;
610                 StorageOperationStatus status;
611                 if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NodeType) {
612                         status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex, user, HEAT_VF_ENV_NAME);
613                 } else {
614                         status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance, updatedContainerVertex);
615                 }
616                 if (status == StorageOperationStatus.OK) {
617                         result = Either.left(updatedContainerVertex);
618                 } else {
619                         result = Either.right(status);
620                 }
621                 return result;
622         }
623
624         private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
625
626                 StorageOperationStatus status;
627
628                 status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
629
630                 if (status != StorageOperationStatus.OK) {
631
632                         return status;
633                 }
634
635                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
636
637                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, instProperties, componentInstance.getUniqueId());
638                 if (status != StorageOperationStatus.OK) {
639                         return status;
640                 }
641
642                 return status;
643         }
644
645         private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
646                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
647
648                 if (calculatedCapabilities != null) {
649                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
650                         calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
651                                 Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
652                                 mapByType.entrySet().forEach(entryPerType -> {
653                                         entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
654                                                 cap.addToPath(componentInstance.getUniqueId());
655                                                 allCalculatedCap.add(entryPerType.getKey(), cap);
656                                         });
657                                 });
658                         });
659
660                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
661                                         componentInstance.getUniqueId());
662
663                         if (calculatedResult != StorageOperationStatus.OK) {
664                                 return calculatedResult;
665                         }
666                         MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
667                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
668
669                         if (calculatedResult != StorageOperationStatus.OK) {
670                                 return calculatedResult;
671                         }
672                 }
673                 Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
674                 if (calculatedRequirements != null) {
675
676                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
677                         calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
678                                 Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
679                                 mapByType.entrySet().forEach(entryPerType -> {
680                                         entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
681                                                 req.addToPath(componentInstance.getUniqueId());
682                                                 allCalculatedReq.add(entryPerType.getKey(), req);
683                                         });
684                                 });
685                         });
686
687                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
688                                         componentInstance.getUniqueId());
689                         if (calculatedResult != StorageOperationStatus.OK) {
690                                 return calculatedResult;
691                         }
692                         MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
693                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
694                         if (calculatedResult != StorageOperationStatus.OK) {
695                                 return calculatedResult;
696                         }
697                 }
698
699                 Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
700                 Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
701
702                 if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
703                         for (MapCapabiltyProperty map : calculatedCapabilitiesProperties.values()) {
704                                 for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
705                                         String newKey = new String(componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
706                                         updateKeyMap.put(newKey, entry.getValue());
707                                 }
708                         }
709                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
710                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty,
711                                         componentInstance.getUniqueId());
712                         if (calculatedResult != StorageOperationStatus.OK) {
713                                 return calculatedResult;
714                         }
715                 }
716                 return StorageOperationStatus.OK;
717         }
718
719         private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
720
721                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originNodeType.getProperties());
722
723                 StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
724                 if (status != StorageOperationStatus.OK) {
725                         return status;
726                 }
727
728                 MapPropertiesDataDefinition instAttributes = new MapPropertiesDataDefinition(originNodeType.getAttributes());
729
730                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
731
732                 if (status != StorageOperationStatus.OK) {
733                         return status;
734                 }
735
736                 return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
737         }
738
739         public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
740                 if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
741                         Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
742
743                         deploymentArtifacts.entrySet().forEach(e -> {
744                                 ArtifactDataDefinition artifact = e.getValue();
745                                 String type = artifact.getArtifactType();
746                                 if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
747                                         ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
748                                         instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
749                                 }
750                         });
751
752                         deploymentArtifacts.putAll(instDeploymentArtifacts);
753                         MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(deploymentArtifacts);
754
755                         return instArtifacts;
756                 }
757                 return null;
758         }
759
760         @SuppressWarnings({ "unchecked" })
761         private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
762                 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
763                 if (deploymentResourceArtifacts == null) {
764                         logger.debug("no deployment artifacts are configured for generated artifacts");
765                         return null;
766                 }
767                 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
768                 if (placeHolderData == null) {
769                         logger.debug("no env type {} are configured for generated artifacts", heatEnvType);
770                         return null;
771                 }
772
773                 String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
774
775                 ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
776
777                 String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
778                 String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
779                 String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
780
781                 artifactInfo.setArtifactDisplayName(artifactName);
782                 artifactInfo.setArtifactLabel(envLabel);
783                 artifactInfo.setArtifactType(artifactType);
784                 artifactInfo.setDescription(artifactDescription);
785                 artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
786                 setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
787                 artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
788                 // clone heat parameters in case of heat env only not VF heat env
789                 if (heatEnvType.equals(HEAT_ENV_NAME)) {
790                         artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
791                 }
792                 setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
793
794                 return artifactInfo;
795         }
796
797         public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
798                 if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
799                         artifactInfo.setTimeout(defaultHeatTimeout);
800                 } else {
801                         artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
802                 }
803         }
804
805         private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
806                 String uniqueId = null;
807
808                 if (resourceId != null) {
809                         uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
810                         artifactInfo.setUniqueId(uniqueId);
811                 }
812                 artifactInfo.setUserIdCreator(user.getUserId());
813                 String fullName = user.getFullName();
814                 artifactInfo.setUpdaterFullName(fullName);
815
816                 long time = System.currentTimeMillis();
817
818                 artifactInfo.setCreatorFullName(fullName);
819                 artifactInfo.setCreationDate(time);
820
821                 artifactInfo.setLastUpdateDate(time);
822                 artifactInfo.setUserIdLastUpdater(user.getUserId());
823
824                 artifactInfo.setMandatory(true);
825         }
826
827         /**
828          * 
829          * @param originNodeType
830          * @param componentInstance
831          * @param updatedContainerVertex
832          * @return
833          */
834         private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
835
836                 Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
837                 MapListCapabiltyDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
838                 StorageOperationStatus calculatedResult;
839                 if (allCalculatedCap != null) {
840                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
841
842                         if (calculatedResult != StorageOperationStatus.OK) {
843                                 return calculatedResult;
844                         }
845                 }
846                 Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
847                 if (capabiltiesProperties != null) {
848                         Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), e -> e.getValue()));
849                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
850                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty, componentInstance.getUniqueId());
851                         if (calculatedResult != StorageOperationStatus.OK) {
852                                 return calculatedResult;
853                         }
854                 }
855
856                 MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
857                 calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
858
859                 if (calculatedResult != StorageOperationStatus.OK) {
860                         return calculatedResult;
861                 }
862
863                 Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
864
865                 MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
866
867                 StorageOperationStatus status;
868                 if (allCalculatedReq != null) {
869                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
870                         if (status != StorageOperationStatus.OK) {
871                                 return status;
872                         }
873                 }
874                 MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
875                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
876                 return StorageOperationStatus.OK;
877
878         }
879
880         public static String createCapPropertyKey(String key, String instanceId) {
881                 StringBuffer sb = new StringBuffer(instanceId);
882                 sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
883                 return sb.toString();
884         }
885         
886         /**
887          * Prepares a map of capabilities lists
888          * Produces a deep copy of the received map of capabilities
889          * Sets values to the specific fields according to received component instance 
890          * @param capabilities
891          * @param componentInstance
892          * @return
893          */
894         public MapListCapabiltyDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
895                 if (capabilities != null) {
896                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
897
898                         capabilities.entrySet().forEach(e -> {
899                                 List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition().stream().map(c -> new CapabilityDataDefinition(c)).collect(Collectors.toList());
900                                 listCapabilities.forEach(cap -> {
901                                         cap.setSource(componentInstance.getComponentUid());
902                                         cap.addToPath(componentInstance.getUniqueId());
903                                         cap.setOwnerId(componentInstance.getUniqueId());
904                                         cap.setOwnerName(componentInstance.getName());
905                                         cap.setLeftOccurrences(cap.getMaxOccurrences());
906                                         allCalculatedCap.add(e.getKey(), cap);
907                                 });
908                         });
909                         return allCalculatedCap;
910                 }
911                 return null;
912         }
913
914         /**
915          * Prepares a map of requirements lists
916          * Produces a deep copy of the received map of requirements
917          * Sets values to the specific fields according to received component instance 
918          * @param requirements
919          * @param componentInstance
920          * @return
921          */
922         public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
923                 if (requirements != null) {
924                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
925
926                         requirements.entrySet().forEach(e -> {
927                                 List<RequirementDataDefinition> listRequirements = e.getValue().getListToscaDataDefinition().stream().map(r -> new RequirementDataDefinition(r)).collect(Collectors.toList());
928                                 listRequirements.forEach(req -> {
929                                         req.setSource(componentInstance.getComponentUid());
930                                         req.addToPath(componentInstance.getUniqueId());
931                                         req.setOwnerId(componentInstance.getUniqueId());
932                                         req.setOwnerName(componentInstance.getName());
933                                         req.setLeftOccurrences(req.getMaxOccurrences());
934                                         allCalculatedReq.add(e.getKey(), req);
935                                 });
936                         });
937                         return allCalculatedReq;
938                 }
939                 return null;
940         }
941
942         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstanceDataDefinition componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
943
944                 StorageOperationStatus result = null;
945                 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
946                 if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
947                         for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
948                                 Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
949                                 if (groupOptional.isPresent()) {
950                                         GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition((GroupDataDefinition) groupOptional.get(), (ComponentInstanceDataDefinition) componentInstance, null);
951                                         groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(a -> a.getUniqueId()).collect(Collectors.toList()));
952                                         groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(a -> a.getArtifactUUID()).collect(Collectors.toList()));
953                                         groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
954                                 }
955                         }
956                 }
957                 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
958                         result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
959                 }
960                 if (result == null) {
961                         result = StorageOperationStatus.OK;
962                 }
963                 return result;
964         }
965
966         private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
967                 String ciOriginComponentUid = resourceInstance.getComponentUid();
968
969                 if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
970                         resourceInstance.setCustomizationUUID(generateCustomizationUUID());
971                 }
972                 ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
973
974                 Long creationDate = resourceInstance.getCreationTime();
975                 Long modificationTime;
976                 if (creationDate == null) {
977                         creationDate = System.currentTimeMillis();
978                         modificationTime = creationDate;
979                 } else {
980                         modificationTime = System.currentTimeMillis();
981                 }
982                 dataDefinition.setComponentUid(ciOriginComponentUid);
983                 dataDefinition.setCreationTime(creationDate);
984                 dataDefinition.setModificationTime(modificationTime);
985                 if (StringUtils.isNotEmpty(instanceNewName)) {
986                         dataDefinition.setName(instanceNewName);
987                         resourceInstance.setName(instanceNewName);
988                 }
989                 if (StringUtils.isNotEmpty(dataDefinition.getName()))
990                         dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
991                 dataDefinition.setIcon(resourceInstance.getIcon());
992                 if (generateUid) {
993                         dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
994                         resourceInstance.setUniqueId(dataDefinition.getUniqueId());
995                 }
996                 if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
997                         dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
998                 if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
999                         dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
1000                 if (originToscaElement != null && dataDefinition.getToscaComponentName() == null)
1001                         dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
1002                 if (dataDefinition.getOriginType() == null && originToscaElement != null) {
1003                         ResourceTypeEnum resourceType = originToscaElement.getResourceType();
1004                         OriginTypeEnum originType = OriginTypeEnum.findByValue(resourceType.name());
1005                         dataDefinition.setOriginType(originType);
1006                 }
1007                 if(dataDefinition.getOriginType()  == OriginTypeEnum.ServiceProxy)
1008                         dataDefinition.setIsProxy(true);
1009         
1010                 return dataDefinition;
1011         }
1012
1013         private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
1014                 Boolean isUniqueName = true;
1015                 try {
1016                         isUniqueName = !container.getComponentInstances().values().stream().filter(ci -> ci.getName() != null && ci.getName().equals(instanceName)).findAny().isPresent();
1017
1018                 } catch (Exception e) {
1019                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
1020                 }
1021                 return isUniqueName;
1022         }
1023
1024         private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
1025                 return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
1026         }
1027
1028         public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef relation) {
1029                 List<RequirementCapabilityRelDef> relations = new ArrayList<>();
1030                 relations.add(relation);
1031                 Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(componentId, relations);
1032                 if (associateResourceInstances.isRight()) {
1033                         return Either.right(associateResourceInstances.right().value());
1034                 }
1035                 return Either.left(associateResourceInstances.left().value().get(0));
1036         }
1037
1038         @SuppressWarnings({ "unchecked" })
1039         public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
1040
1041                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1042                 if (containerVEither.isRight()) {
1043                         TitanOperationStatus error = containerVEither.right().value();
1044                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1045                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1046                 }
1047                 GraphVertex containerV = containerVEither.left().value();
1048                 List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
1049                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1050                 if (capResult.isRight()) {
1051                         return Either.right(capResult.right().value());
1052
1053                 }
1054                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
1055
1056                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1057                 if (capResult.isRight()) {
1058                         return Either.right(capResult.right().value());
1059
1060                 }
1061                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
1062
1063                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1064                 if (reqResult.isRight()) {
1065                         return Either.right(reqResult.right().value());
1066                 }
1067                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1068
1069                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1070                 if (reqResult.isRight()) {
1071                         return Either.right(reqResult.right().value());
1072                 }
1073                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
1074
1075                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1076                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1077
1078                 StorageOperationStatus status;
1079                 List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
1080                 for (RequirementCapabilityRelDef relation : relations) {
1081
1082                         String fromNode = relation.getFromNode();
1083                         String toNode = relation.getToNode();
1084                         List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
1085                         if (relationships == null || relationships.isEmpty()) {
1086                                 BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1087                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
1088                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
1089                         }
1090
1091                         for (CapabilityRequirementRelationship immutablePair : relationships) {
1092                                 String requirement = immutablePair.getRelation().getRequirement();
1093
1094                                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair.getRelation(), calculatedCapabilty, calculatedRequirement, fullFilledCapabilty, fullfilledRequirement,
1095                                                 compositionDataDefinition, containerV.getUniqueId());
1096
1097                                 if (associateRes.isRight()) {
1098                                         status = associateRes.right().value();
1099                                         BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1100                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
1101                                         return Either.right(status);
1102                                 }
1103
1104                                 RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) associateRes.left().value().get(JsonPresentationFields.RELATIONSHIP);
1105                                 RelationshipImpl relationshipImplResult = new RelationshipImpl();
1106                                 relationshipImplResult.setType(relationshipInstData.getType());
1107                                 RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
1108                                 requirementAndRelationshipPair.setCapability(immutablePair.getRelation().getCapability());
1109                                 requirementAndRelationshipPair.setRequirement(immutablePair.getRelation().getRequirement());
1110                                 requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
1111                                 requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
1112                                 requirementAndRelationshipPair.setCapabilityUid(immutablePair.getRelation().getCapabilityUid());
1113                                 requirementAndRelationshipPair.setRequirementUid(immutablePair.getRelation().getRequirementUid());
1114                                 requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
1115                                 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
1116                                 capReqRel.setRelation(requirementAndRelationshipPair);
1117                                 capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPAPILITY));
1118                                 capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
1119                                 relationshipsResult.add(capReqRel);
1120                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
1121                                 status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
1122                                 if (status != StorageOperationStatus.OK) {
1123                                         return Either.right(status);
1124                                 }
1125                                 status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
1126                                 if (status != StorageOperationStatus.OK) {
1127                                         return Either.right(status);
1128                                 }
1129                         }
1130                         RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef();
1131                         capabilityRelDef.setFromNode(fromNode);
1132                         capabilityRelDef.setToNode(toNode);
1133                         capabilityRelDef.setRelationships(relationshipsResult);
1134                         relationsList.add(capabilityRelDef);
1135                 }
1136                 // update metadata of container and composition json
1137                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1138                 if (status != StorageOperationStatus.OK) {
1139                         return Either.right(status);
1140                 }
1141
1142                 return Either.left(relationsList);
1143         }
1144
1145         private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult,
1146                         Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
1147                         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
1148                 containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1149                 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
1150                 if (updateElement.isRight()) {
1151                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
1152                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1153                 }
1154                 // update cap/req jsons, fulfilled cap/req jsons!!!!!
1155                 Either<GraphVertex, TitanOperationStatus> status;
1156                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
1157                 status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1158                 if (status.isRight()) {
1159                         TitanOperationStatus error = status.right().value();
1160                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
1161                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1162                 }
1163
1164                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1165                 status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1166                 if (status.isRight()) {
1167                         TitanOperationStatus error = status.right().value();
1168                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
1169                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1170                 }
1171
1172                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
1173                 status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1174                 if (status.isRight()) {
1175                         TitanOperationStatus error = status.right().value();
1176                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
1177                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1178                 }
1179
1180                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
1181                 status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1182                 if (status.isRight()) {
1183                         TitanOperationStatus error = status.right().value();
1184                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
1185                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1186                 }
1187                 return StorageOperationStatus.OK;
1188         }
1189
1190         @SuppressWarnings({ "unchecked" })
1191         public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
1192                 if (requirementDef.getRelationships() == null) {
1193                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
1194                         return Either.right(StorageOperationStatus.BAD_REQUEST);
1195                 }
1196
1197                 String fromResInstanceUid = requirementDef.getFromNode();
1198                 String toResInstanceUid = requirementDef.getToNode();
1199
1200                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1201                 if (containerVEither.isRight()) {
1202                         TitanOperationStatus error = containerVEither.right().value();
1203                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1204                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1205                 }
1206                 GraphVertex containerV = containerVEither.left().value();
1207
1208                 // DE191707 - validations
1209                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1210                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1211                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1212                 ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
1213                 if (ciFrom == null) {
1214                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
1215                         return Either.right(StorageOperationStatus.NOT_FOUND);
1216
1217                 }
1218                 ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
1219                 if (ciFrom == ciTo) {
1220                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
1221                         return Either.right(StorageOperationStatus.NOT_FOUND);
1222
1223                 }
1224                 Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
1225
1226                 List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
1227                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1228                 if (capResult.isRight()) {
1229                         return Either.right(capResult.right().value());
1230                 }
1231                 Map<String, MapListCapabiltyDataDefinition> calculatedCapability = capResult.left().value().getRight();
1232
1233                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1234                 if (capResult.isRight()) {
1235                         return Either.right(capResult.right().value());
1236
1237                 }
1238                 Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1239
1240                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1241                 if (reqResult.isRight()) {
1242                         return Either.right(reqResult.right().value());
1243                 }
1244                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1245
1246                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1247                 if (reqResult.isRight()) {
1248                         return Either.right(reqResult.right().value());
1249                 }
1250                 Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1251
1252                 for (CapabilityRequirementRelationship relationPair : relationPairList) {
1253                         Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
1254                         boolean isDeleted = false;
1255                         while (iterator.hasNext()) {
1256                                 Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
1257                                 RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
1258                                 if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson.getUniqueId().equals(relationPair.getRelation().getId())) {
1259                                         if (relationPair.getRelation().equalsTo(relationInJson)) {
1260                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(),
1261                                                                 relationInJson.getCapabilityOwnerId(), relationInJson.getRequirementOwnerId());
1262                                                 iterator.remove();
1263
1264                                                 // update calculated cap/req
1265                                                 StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability, toResInstanceUid, relationInJson, relationPair);
1266                                                 if (status != StorageOperationStatus.OK) {
1267                                                         return Either.right(status);
1268                                                 }
1269                                                 status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid, relationInJson, relationPair);
1270                                                 if (status != StorageOperationStatus.OK) {
1271                                                         return Either.right(status);
1272                                                 }
1273                                                 isDeleted = true;
1274                                         }
1275                                 }
1276                         }
1277                         if (!isDeleted) {
1278                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
1279                                                 relationPair.getRelation().getCapabilityOwnerId(), relationPair.getRelation().getRequirementOwnerId());
1280                                 return Either.right(StorageOperationStatus.NOT_FOUND);
1281                         }
1282                 }
1283                 StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
1284                 if (status != StorageOperationStatus.OK) {
1285                         return Either.right(status);
1286                 }
1287                 status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
1288                 if (status != StorageOperationStatus.OK) {
1289                         return Either.right(status);
1290                 }
1291
1292                 // update jsons
1293                 // update metadata of container and composition json
1294                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1295                 if (status != StorageOperationStatus.OK) {
1296                         return Either.right(status);
1297                 }
1298
1299                 return Either.left(requirementDef);
1300         }
1301         
1302         /**
1303          * Retrieves fulfilled requirement according to relation and received predicate
1304          * @param componentId
1305          * @param instanceId
1306          * @param foundRelation
1307          * @param predicate
1308          * @return
1309          */
1310         public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
1311
1312                 Either<RequirementDataDefinition, StorageOperationStatus> result = null;
1313                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
1314                 MapListRequirementDataDefinition reqMapOfLists = null;
1315                 Optional<RequirementDataDefinition> foundRequirement;
1316                 RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1317                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1318                 if (containerVEither.isRight()) {
1319                         TitanOperationStatus error = containerVEither.right().value();
1320                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1321                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1322                 }
1323                 if(result == null){
1324                         GraphVertex containerV = containerVEither.left().value();
1325                         reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1326                         if (reqFullResult.isRight()) {
1327                                 result = Either.right(reqFullResult.right().value());
1328                         }
1329                 }
1330                 if(result == null){
1331                         Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1332                         reqMapOfLists = fulfilledRequirement.get(instanceId);   
1333                         if(reqMapOfLists == null){
1334                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1335                         }
1336                 }
1337                 if(result == null && reqMapOfLists != null){
1338                         for(ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()){
1339                                 foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req)).findFirst();
1340                                 if(foundRequirement.isPresent()){
1341                                         result = Either.left(foundRequirement.get());
1342                                 }
1343                         }
1344                 }
1345                 return result;
1346         }
1347         
1348         /**
1349          * Retrieves fulfilled capability according to relation and received predicate
1350          * @param componentId
1351          * @param instanceId
1352          * @param foundRelation
1353          * @param predicate
1354          * @return
1355          */
1356         public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
1357                 
1358                 Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
1359                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = null;
1360                 MapListCapabiltyDataDefinition capMapOfLists = null;
1361                 Optional<CapabilityDataDefinition> foundRequirement;
1362                 
1363                 RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1364                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1365                 if (containerVEither.isRight()) {
1366                         TitanOperationStatus error = containerVEither.right().value();
1367                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1368                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1369                 }
1370                 if(result == null){
1371                         GraphVertex containerV = containerVEither.left().value();
1372                         capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1373                         if (capFullResult.isRight()) {
1374                                 result = Either.right(capFullResult.right().value());
1375                         }
1376                 }
1377                 if(result == null){
1378                         Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1379                         capMapOfLists = fulfilledCapability.get(instanceId);
1380                         if(capMapOfLists == null){
1381                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1382                         }
1383                 }
1384                 if(result == null && capMapOfLists != null){
1385                         for(ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()){
1386                                 foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap)).findFirst();
1387                                 if(foundRequirement.isPresent()){
1388                                         result = Either.left(foundRequirement.get());
1389                                 }
1390                         }
1391                 }
1392                 return result;
1393         }
1394
1395         private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1396                         RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1397                 StorageOperationStatus status;
1398                 String hereIsTheKey = null;
1399                 MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
1400                 if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
1401                         // move from fulfilled
1402                         status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1403                 } else {
1404                         hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1405                         ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1406                         Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
1407                                         .filter(req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())).findFirst();
1408
1409                         if (requirementOptional.isPresent()) {
1410
1411                                 RequirementDataDefinition requirement = requirementOptional.get();
1412                                 String leftOccurrences = requirement.getLeftOccurrences();
1413                                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1414                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1415                                         ++leftIntValue;
1416                                         requirement.setLeftOccurrences(String.valueOf(leftIntValue));
1417                                 }
1418                                 if(relationship != null){
1419                                         relationship.setRequirement(requirement);
1420                                 }
1421                                 status = StorageOperationStatus.OK;
1422                         } else {
1423                                 // move from fulfilled
1424                                 status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1425                         }
1426                 }
1427                 return status;
1428         }
1429
1430         private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
1431                         RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1432                 StorageOperationStatus status;
1433                 String hereIsTheKey = null;
1434                 MapListCapabiltyDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
1435                 if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
1436                         // move from fulfilled
1437                         status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1438                 } else {
1439                         hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1440                         ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1441                         Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream().filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
1442                                         .findFirst();
1443
1444                         if (capabilityOptional.isPresent()) {
1445
1446                                 CapabilityDataDefinition capability = capabilityOptional.get();
1447                                 String leftOccurrences = capability.getLeftOccurrences();
1448                                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1449                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1450                                         ++leftIntValue;
1451                                         capability.setLeftOccurrences(String.valueOf(leftIntValue));
1452                                 }
1453                                 if(relationship != null){
1454                                         relationship.setCapability(capability);
1455                                 }
1456                                 status = StorageOperationStatus.OK;
1457                         } else {
1458                                 // move from fulfilled
1459                                 status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1460                         }
1461                 }
1462                 return status;
1463         }
1464
1465         private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
1466                         RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1467                 MapListCapabiltyDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
1468                 if (capByInstance == null) {
1469                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
1470                         return StorageOperationStatus.GENERAL_ERROR;
1471                 }
1472                 if (null == hereIsTheKey)
1473                         hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1474                 if (null == hereIsTheKey) {
1475                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(), toResInstanceUid);
1476                         return StorageOperationStatus.GENERAL_ERROR;
1477                 }
1478                 ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1479                 Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
1480                 boolean found = false;
1481                 while (iterator.hasNext()) {
1482                         CapabilityDataDefinition cap = iterator.next();
1483                         if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
1484                                 found = true;
1485                                 iterator.remove();
1486                                 // return to calculated list
1487                                 String leftOccurrences = cap.getLeftOccurrences();
1488                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1489                                 ++leftIntValue;
1490                                 cap.setLeftOccurrences(String.valueOf(leftIntValue));
1491
1492                                 MapListCapabiltyDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
1493                                 if (mapListCapaDataDef == null) {
1494                                         mapListCapaDataDef = new MapListCapabiltyDataDefinition();
1495                                 }
1496                                 ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
1497                                 if (findByKey == null) {
1498                                         findByKey = new ListCapabilityDataDefinition();
1499                                         mapListCapaDataDef.put(hereIsTheKey, findByKey);
1500                                 }
1501                                 findByKey.add(cap);
1502                                 if(relationship!= null)
1503                                         relationship.setCapability(cap);
1504                                 break;
1505                         }
1506                 }
1507                 if (found == false) {
1508                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getCapabilityOwnerId(), toResInstanceUid);
1509                         return StorageOperationStatus.GENERAL_ERROR;
1510                 }
1511                 return StorageOperationStatus.OK;
1512         }
1513
1514         private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1515                         RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1516                 MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
1517                 if (reqByInstance == null) {
1518                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
1519                         return StorageOperationStatus.GENERAL_ERROR;
1520                 }
1521                 if (null == hereIsTheKey)
1522                         hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1523                 if (null == hereIsTheKey) {
1524                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(), fromResInstanceUid);
1525                         return StorageOperationStatus.GENERAL_ERROR;
1526                 }
1527                 ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1528                 Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
1529                 boolean found = false;
1530                 while (iterator.hasNext()) {
1531                         RequirementDataDefinition req = iterator.next();
1532                         if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
1533                                 found = true;
1534                                 iterator.remove();
1535                                 // return to calculated list
1536                                 String leftOccurrences = req.getLeftOccurrences();
1537                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1538                                 ++leftIntValue;
1539                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1540
1541                                 MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
1542                                 if (mapListReqDataDef == null) {
1543                                         mapListReqDataDef = new MapListRequirementDataDefinition();
1544                                 }
1545                                 ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
1546                                 if (findByKey == null) {
1547                                         findByKey = new ListRequirementDataDefinition();
1548                                         mapListReqDataDef.put(hereIsTheKey, findByKey);
1549                                 }
1550                                 findByKey.add(req);
1551                                 if(relationship!= null)
1552                                         relationship.setRequirement(req);
1553                                 break;
1554                         }
1555                 }
1556                 if (found == false) {
1557                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getRequirementOwnerId(), fromResInstanceUid);
1558                         return StorageOperationStatus.GENERAL_ERROR;
1559                 }
1560                 return StorageOperationStatus.OK;
1561
1562         }
1563
1564         public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
1565                 ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
1566
1567                 if (componentInstance == null) {
1568                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
1569                         return StorageOperationStatus.NOT_FOUND;
1570                 }
1571                 UUID uuid = UUID.randomUUID();
1572                 componentInstance.setCustomizationUUID(uuid.toString());
1573
1574                 return StorageOperationStatus.OK;
1575         }
1576
1577         public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair,
1578                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1579                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
1580                 String requirement = relationPair.getRequirement();
1581                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1582
1583                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
1584
1585                 ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
1586                 if (fromResourceInstData == null) {
1587                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
1588                         return Either.right(StorageOperationStatus.NOT_FOUND);
1589                 }
1590                 ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
1591                 if (toResourceInstData == null) {
1592                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
1593                         return Either.right(StorageOperationStatus.NOT_FOUND);
1594                 }
1595
1596                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
1597                                 fullfilledRequirement, containerId);
1598                 if (reqVsCap.isRight()) {
1599                         StorageOperationStatus status = reqVsCap.right().value();
1600                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
1601                         return Either.right(status);
1602                 }
1603                 Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
1604
1605                 // add to json new relations
1606                 compositionDataDefinition.addRelation(((RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(), (RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP));
1607
1608                 return Either.left(relationship);
1609         }
1610
1611         private Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
1612
1613                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, TitanOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
1614                 if (calculatedCapabiltyEither.isRight()) {
1615                         TitanOperationStatus error = calculatedCapabiltyEither.right().value();
1616                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
1617                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1618                 }
1619                 Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
1620                 return Either.left(calculatedCapabilty);
1621         }
1622
1623         private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
1624                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, TitanOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
1625                 if (calculatedRequirementEither.isRight()) {
1626                         TitanOperationStatus error = calculatedRequirementEither.right().value();
1627                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
1628                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1629                 }
1630                 Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
1631                 return Either.left(calculatedRequirement);
1632         }
1633
1634         @SuppressWarnings("unchecked")
1635         private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance, RelationshipInfo relationPair,
1636                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1637                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
1638                 String type = relationPair.getRelationship().getType();
1639                 // capability
1640
1641                 String toInstId = toResInstance.getUniqueId();
1642                 MapListCapabiltyDataDefinition mapListCapabiltyDataDefinition = calculatedCapabilty.get(toInstId);
1643                 Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
1644
1645                 if (mapListCapabiltyDataDefinition == null) {
1646                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
1647                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1648                 }
1649                 ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabiltyDataDefinition.getMapToscaDataDefinition().get(type);
1650                 if (listCapabilityDataDefinition == null) {
1651                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
1652                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1653                 }
1654                 CapabilityDataDefinition capabilityForRelation = null;
1655                 Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
1656                 while (iteratorCap.hasNext()) {
1657                         CapabilityDataDefinition cap = iteratorCap.next();
1658                         if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
1659                                 capabilityForRelation = cap;
1660                                 capReqRelationship.put(JsonPresentationFields.CAPAPILITY, (T)capabilityForRelation);
1661                                 String leftOccurrences = cap.getLeftOccurrences();
1662                                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1663                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1664                                         if (leftIntValue > 0) {
1665                                                 --leftIntValue;
1666                                                 capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
1667                                                 if (leftIntValue == 0) {
1668                                                         // remove from calculated
1669                                                         iteratorCap.remove();
1670                                                         // move to fulfilled
1671                                                         MapListCapabiltyDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
1672                                                         if (mapListCapabiltyFullFilledInst == null) {
1673                                                                 mapListCapabiltyFullFilledInst = new MapListCapabiltyDataDefinition();
1674                                                                 fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
1675                                                         }
1676
1677                                                         ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
1678                                                         if (listCapabilityFull == null) {
1679                                                                 listCapabilityFull = new ListCapabilityDataDefinition();
1680                                                                 mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
1681                                                         }
1682                                                         listCapabilityFull.add(capabilityForRelation);
1683                                                 }
1684                                                 break;
1685                                         } else {
1686                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabilityForRelation.getType(), toInstId, containerId);
1687                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1688                                         }
1689                                 }
1690                         }
1691                 }
1692                 if (capabilityForRelation == null) {
1693                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
1694                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1695                 }
1696
1697                 // requirements
1698                 String fromInstId = fromResInstance.getUniqueId();
1699                 MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
1700                 if (mapListRequirementDataDefinition == null) {
1701                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
1702                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1703                 }
1704                 ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
1705                 if (listRequirementDataDefinition == null) {
1706                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
1707                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1708                 }
1709
1710                 RequirementDataDefinition requirementForRelation = null;
1711                 Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
1712                 while (iteratorReq.hasNext()) {
1713                         RequirementDataDefinition req = iteratorReq.next();
1714                         if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
1715                                 requirementForRelation = req;
1716                                 capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T)requirementForRelation);
1717                                 String leftOccurrences = req.getLeftOccurrences();
1718                                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1719                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1720                                         if (leftIntValue > 0) {
1721                                                 --leftIntValue;
1722                                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1723                                                 if (leftIntValue == 0) {
1724                                                         // remove from calculated
1725                                                         iteratorReq.remove();
1726                                                         // move to fulfilled
1727                                                         MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
1728                                                         if (mapListRequirementFullFilledInst == null) {
1729                                                                 mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
1730                                                                 fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
1731                                                         }
1732
1733                                                         ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
1734                                                         if (listRequirementFull == null) {
1735                                                                 listRequirementFull = new ListRequirementDataDefinition();
1736                                                                 mapListRequirementFullFilledInst.put(type, listRequirementFull);
1737                                                         }
1738                                                         listRequirementFull.add(requirementForRelation);
1739                                                 }
1740                                                 break;
1741                                         } else {
1742                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
1743                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1744                                         }
1745                                 }
1746                         }
1747                 }
1748                 if (requirementForRelation == null) {
1749                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch requirement for type {} for instance {} in container {}.", type, toInstId, containerId);
1750                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1751                 }
1752                 if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
1753                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No macth for capability from type {} and requirement {} from {} to {} in container {}.", capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId,
1754                                         toInstId, containerId);
1755                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1756                 }
1757
1758                 RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair);
1759                 if(requirementForRelation.getRelationship() != null)
1760                         relationshipTypeData.setType(requirementForRelation.getRelationship());
1761                 capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T)relationshipTypeData);
1762                 return Either.left(capReqRelationship);
1763         }
1764
1765         private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair) {
1766
1767                 RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
1768                 relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
1769
1770                 relationshipInstData.setType(relationPair.getRelationship().getType());
1771                 Long creationDate = System.currentTimeMillis();
1772                 relationshipInstData.setCreationTime(creationDate);
1773                 relationshipInstData.setModificationTime(creationDate);
1774                 relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
1775                 relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
1776                 relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
1777                 relationshipInstData.setRequirementId(relationPair.getRequirementUid());
1778                 relationshipInstData.setFromId(fromResInstanceUid);
1779                 relationshipInstData.setToId(toInstId);
1780                 relationshipInstData.setRequirement(relationPair.getRequirement());
1781                 relationshipInstData.setCapability(relationPair.getCapability());
1782
1783                 return relationshipInstData;
1784         }
1785
1786         public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
1787
1788                 StorageOperationStatus result = null;
1789                 String containerId = containerComponent.getUniqueId();
1790                 Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
1791                 Either<GraphVertex, TitanOperationStatus> updateElement = null;
1792                 if (!validateInstanceNames(resourcesInstancesMap)) {
1793                         result = StorageOperationStatus.INCONSISTENCY;
1794                 }
1795                 if (result == null) {
1796                         if (!validateInstanceNames(resourcesInstancesMap)) {
1797                                 result = StorageOperationStatus.INCONSISTENCY;
1798                         }
1799                 }
1800                 if (result == null && !allowDeleted) {
1801                         if (!validateDeletedResources(resourcesInstancesMap)) {
1802                                 result = StorageOperationStatus.INCONSISTENCY;
1803                         }
1804                 }
1805                 if (result == null) {
1806                         instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
1807                 }
1808                 if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
1809                         containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1810                         Map<String, CompositionDataDefinition> compositions = new HashMap<>();
1811                         CompositionDataDefinition composition = new CompositionDataDefinition();
1812                         composition.setComponentInstances(instancesJsonData);
1813                         compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
1814                         containerVertex.setJson(compositions);
1815                         updateElement = titanDao.updateVertex(containerVertex);
1816                         if (updateElement.isRight()) {
1817                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
1818                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1819                         }
1820                 }
1821                 if (result == null) {
1822                         result = StorageOperationStatus.OK;
1823                 }
1824                 return result;
1825         }
1826
1827         private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
1828
1829                 Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
1830                 for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
1831                         ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
1832                         instances.put(instance.getUniqueId(), instance);
1833                 }
1834                 return instances;
1835         }
1836
1837         private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1838                 boolean result = true;
1839                 for (Resource resource : resourcesInstancesMap.values()) {
1840                         if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
1841                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
1842                                 result = false;
1843                                 break;
1844                         }
1845                 }
1846                 return result;
1847         }
1848
1849         private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1850                 boolean result = true;
1851                 Set<String> names = new HashSet<>();
1852                 for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
1853                         if (StringUtils.isEmpty(instance.getName())) {
1854                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
1855                                 result = false;
1856                                 break;
1857                         } else if (names.contains(instance.getName())) {
1858                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ", instance.getName());
1859                                 result = false;
1860                                 break;
1861                         } else {
1862                                 names.add(instance.getName());
1863                         }
1864                 }
1865                 return result;
1866         }
1867
1868         public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
1869                 return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
1870         }
1871
1872         public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
1873                 return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS);
1874         }
1875
1876         public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexType) {
1877                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
1878                 if (metadataVertex.isRight()) {
1879                         TitanOperationStatus status = metadataVertex.right().value();
1880                         if (status == TitanOperationStatus.NOT_FOUND) {
1881                                 status = TitanOperationStatus.INVALID_ID;
1882                         }
1883                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1884                 }
1885                 MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
1886                 return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
1887
1888         }
1889
1890         @SuppressWarnings({ "unchecked" })
1891         public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
1892                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1893                 if (metadataVertex.isRight()) {
1894                         TitanOperationStatus status = metadataVertex.right().value();
1895                         if (status == TitanOperationStatus.NOT_FOUND) {
1896                                 status = TitanOperationStatus.INVALID_ID;
1897                         }
1898                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1899                 }
1900                 GraphVertex metaVertex = metadataVertex.left().value();
1901                 Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
1902                 CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1903                 StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
1904                 if (status != StorageOperationStatus.OK) {
1905                         logger.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
1906                         return status;
1907                 }
1908                 Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(metaVertex);
1909                 if (updateVertex.isRight()) {
1910                         logger.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
1911                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
1912                 }
1913                 return StorageOperationStatus.OK;
1914         }
1915
1916         public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
1917                 if (groupInstances != null) {
1918                         Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
1919                         if (dataFromGraph.isRight()) {
1920                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
1921                         }
1922                         MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
1923                         if (grInstPerInstance == null) {
1924                                 logger.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
1925                                 return StorageOperationStatus.NOT_FOUND;
1926                         }
1927                         for (String instGroupForUpdate : groupInstances) {
1928                                 GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
1929                                 if (groupInst == null) {
1930                                         logger.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
1931                                         continue;
1932                                 }
1933                                 UUID uuid = UUID.randomUUID();
1934                                 groupInst.setCustomizationUUID(uuid.toString());
1935                         }
1936
1937                 }
1938                 return StorageOperationStatus.OK;
1939         }
1940
1941         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
1942
1943                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
1944                                 new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(gi -> gi.getName(), gi -> gi))), componentInstance.getUniqueId());
1945         }
1946
1947         public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
1948
1949                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
1950                                 componentInstance.getUniqueId());
1951         }
1952
1953         public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1954
1955                 List<String> pathKeys = new ArrayList<>();
1956                 pathKeys.add(componentInstanceId);
1957                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1958         }
1959
1960         public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, String capabilityUniqueId, ComponentInstanceProperty property) {
1961                 List<String> pathKeys = new ArrayList<>();
1962                 pathKeys.add(componentInstanceId);
1963                 pathKeys.add(capabilityUniqueId);
1964                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1965         }
1966
1967         public StorageOperationStatus overrideComponentCapabilitiesProperties(Component containerComponent, Map<String, MapCapabiltyProperty> capabilityPropertyMap) {
1968                 return overrideToscaDataOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilityPropertyMap);
1969         }
1970
1971         public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1972                 List<String> pathKeys = new ArrayList<>();
1973                 pathKeys.add(componentInstanceId);
1974                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1975         }
1976
1977         public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
1978                 List<String> pathKeys = new ArrayList<>();
1979                 pathKeys.add(componentInstanceId);
1980                 return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
1981         }
1982
1983         public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
1984
1985                 List<String> pathKeys = new ArrayList<>();
1986                 pathKeys.add(componentInstanceId);
1987                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
1988         }
1989
1990         public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) {
1991                 List<String> pathKeys = new ArrayList<>();
1992                 pathKeys.add(componentInstanceId);
1993                 return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME);
1994         }
1995
1996         public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
1997                 List<String> pathKeys = new ArrayList<>();
1998                 pathKeys.add(componentInstanceId);
1999                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
2000         }
2001
2002 }