f59f097bdbaaf257ccc9eb42694843ce9c9b7416
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.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                         }
543                 }
544                 return StorageOperationStatus.OK;
545         }
546
547         private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
548                 StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
549                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
550                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
551                         return status;
552                 }
553                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceId);
554                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
555                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
556                         return status;
557                 }
558                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
559                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
560                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
561                         return status;
562                 }
563                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
564                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
565                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
566                         return status;
567                 }
568                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
569                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
570                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
571                         return status;
572                 }
573                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, componentInstanceId);
574                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
575                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove attributes for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
576                         return status;
577                 }
578                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, componentInstanceId);
579                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
580                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove properties for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
581                         return status;
582                 }
583                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, componentInstanceId);
584                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
585                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
586                         return status;
587                 }
588                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, componentInstanceId);
589                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
590                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
591                         return status;
592                 }
593                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
594                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
595                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance deployment artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
596                         return status;
597                 }
598                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS, componentInstanceId);
599                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
600                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
601                         return status;
602                 }
603                 return StorageOperationStatus.OK;
604         }
605
606         protected Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user) {
607
608                 Either<GraphVertex, StorageOperationStatus> result;
609                 StorageOperationStatus status;
610                 if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NodeType) {
611                         status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex, user, HEAT_VF_ENV_NAME);
612                 } else {
613                         status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance, updatedContainerVertex);
614                 }
615                 if (status == StorageOperationStatus.OK) {
616                         result = Either.left(updatedContainerVertex);
617                 } else {
618                         result = Either.right(status);
619                 }
620                 return result;
621         }
622
623         private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
624
625                 StorageOperationStatus status;
626
627                 status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
628
629                 if (status != StorageOperationStatus.OK) {
630
631                         return status;
632                 }
633
634                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
635
636                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, instProperties, componentInstance.getUniqueId());
637                 if (status != StorageOperationStatus.OK) {
638                         return status;
639                 }
640
641                 return status;
642         }
643
644         private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
645                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
646
647                 if (calculatedCapabilities != null) {
648                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
649                         calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
650                                 Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
651                                 mapByType.entrySet().forEach(entryPerType -> {
652                                         entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
653                                                 cap.addToPath(componentInstance.getUniqueId());
654                                                 allCalculatedCap.add(entryPerType.getKey(), cap);
655                                         });
656                                 });
657                         });
658
659                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
660                                         componentInstance.getUniqueId());
661
662                         if (calculatedResult != StorageOperationStatus.OK) {
663                                 return calculatedResult;
664                         }
665                         MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
666                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
667
668                         if (calculatedResult != StorageOperationStatus.OK) {
669                                 return calculatedResult;
670                         }
671                 }
672                 Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
673                 if (calculatedRequirements != null) {
674
675                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
676                         calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
677                                 Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
678                                 mapByType.entrySet().forEach(entryPerType -> {
679                                         entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
680                                                 req.addToPath(componentInstance.getUniqueId());
681                                                 allCalculatedReq.add(entryPerType.getKey(), req);
682                                         });
683                                 });
684                         });
685
686                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
687                                         componentInstance.getUniqueId());
688                         if (calculatedResult != StorageOperationStatus.OK) {
689                                 return calculatedResult;
690                         }
691                         MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
692                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
693                         if (calculatedResult != StorageOperationStatus.OK) {
694                                 return calculatedResult;
695                         }
696                 }
697
698                 Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
699                 Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
700
701                 if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
702                         for (MapCapabiltyProperty map : calculatedCapabilitiesProperties.values()) {
703                                 for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
704                                         String newKey = new String(componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
705                                         updateKeyMap.put(newKey, entry.getValue());
706                                 }
707                         }
708                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
709                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty,
710                                         componentInstance.getUniqueId());
711                         if (calculatedResult != StorageOperationStatus.OK) {
712                                 return calculatedResult;
713                         }
714                 }
715                 return StorageOperationStatus.OK;
716         }
717
718         private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
719
720                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originNodeType.getProperties());
721
722                 StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
723                 if (status != StorageOperationStatus.OK) {
724                         return status;
725                 }
726
727                 MapPropertiesDataDefinition instAttributes = new MapPropertiesDataDefinition(originNodeType.getAttributes());
728
729                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
730
731                 if (status != StorageOperationStatus.OK) {
732                         return status;
733                 }
734
735                 return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
736         }
737
738         public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
739                 if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
740                         Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
741
742                         deploymentArtifacts.entrySet().forEach(e -> {
743                                 ArtifactDataDefinition artifact = e.getValue();
744                                 String type = artifact.getArtifactType();
745                                 if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
746                                         ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
747                                         instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
748                                 }
749                         });
750
751                         deploymentArtifacts.putAll(instDeploymentArtifacts);
752                         MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(deploymentArtifacts);
753
754                         return instArtifacts;
755                 }
756                 return null;
757         }
758
759         @SuppressWarnings({ "unchecked" })
760         private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
761                 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
762                 if (deploymentResourceArtifacts == null) {
763                         logger.debug("no deployment artifacts are configured for generated artifacts");
764                         return null;
765                 }
766                 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
767                 if (placeHolderData == null) {
768                         logger.debug("no env type {} are configured for generated artifacts", heatEnvType);
769                         return null;
770                 }
771
772                 String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
773
774                 ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
775
776                 String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
777                 String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
778                 String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
779
780                 artifactInfo.setArtifactDisplayName(artifactName);
781                 artifactInfo.setArtifactLabel(envLabel);
782                 artifactInfo.setArtifactType(artifactType);
783                 artifactInfo.setDescription(artifactDescription);
784                 artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
785                 setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
786                 artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
787                 // clone heat parameters in case of heat env only not VF heat env
788                 if (heatEnvType.equals(HEAT_ENV_NAME)) {
789                         artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
790                 }
791                 setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
792
793                 return artifactInfo;
794         }
795
796         public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
797                 if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
798                         artifactInfo.setTimeout(defaultHeatTimeout);
799                 } else {
800                         artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
801                 }
802         }
803
804         private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
805                 String uniqueId = null;
806
807                 if (resourceId != null) {
808                         uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
809                         artifactInfo.setUniqueId(uniqueId);
810                 }
811                 artifactInfo.setUserIdCreator(user.getUserId());
812                 String fullName = user.getFullName();
813                 artifactInfo.setUpdaterFullName(fullName);
814
815                 long time = System.currentTimeMillis();
816
817                 artifactInfo.setCreatorFullName(fullName);
818                 artifactInfo.setCreationDate(time);
819
820                 artifactInfo.setLastUpdateDate(time);
821                 artifactInfo.setUserIdLastUpdater(user.getUserId());
822
823                 artifactInfo.setMandatory(true);
824         }
825
826         /**
827          * 
828          * @param originNodeType
829          * @param componentInstance
830          * @param updatedContainerVertex
831          * @return
832          */
833         private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
834
835                 Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
836                 MapListCapabiltyDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
837                 StorageOperationStatus calculatedResult;
838                 if (allCalculatedCap != null) {
839                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
840
841                         if (calculatedResult != StorageOperationStatus.OK) {
842                                 return calculatedResult;
843                         }
844                 }
845                 Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
846                 if (capabiltiesProperties != null) {
847                         Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), e -> e.getValue()));
848                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
849                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty, componentInstance.getUniqueId());
850                         if (calculatedResult != StorageOperationStatus.OK) {
851                                 return calculatedResult;
852                         }
853                 }
854
855                 MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
856                 calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
857
858                 if (calculatedResult != StorageOperationStatus.OK) {
859                         return calculatedResult;
860                 }
861
862                 Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
863
864                 MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
865
866                 StorageOperationStatus status;
867                 if (allCalculatedReq != null) {
868                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
869                         if (status != StorageOperationStatus.OK) {
870                                 return status;
871                         }
872                 }
873                 MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
874                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
875                 return StorageOperationStatus.OK;
876
877         }
878
879         public static String createCapPropertyKey(String key, String instanceId) {
880                 StringBuffer sb = new StringBuffer(instanceId);
881                 sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
882                 return sb.toString();
883         }
884         
885         /**
886          * Prepares a map of capabilities lists
887          * Produces a deep copy of the received map of capabilities
888          * Sets values to the specific fields according to received component instance 
889          * @param capabilities
890          * @param componentInstance
891          * @return
892          */
893         public MapListCapabiltyDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
894                 if (capabilities != null) {
895                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
896
897                         capabilities.entrySet().forEach(e -> {
898                                 List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition().stream().map(c -> new CapabilityDataDefinition(c)).collect(Collectors.toList());
899                                 listCapabilities.forEach(cap -> {
900                                         cap.setSource(componentInstance.getComponentUid());
901                                         cap.addToPath(componentInstance.getUniqueId());
902                                         cap.setOwnerId(componentInstance.getUniqueId());
903                                         cap.setOwnerName(componentInstance.getName());
904                                         cap.setLeftOccurrences(cap.getMaxOccurrences());
905                                         allCalculatedCap.add(e.getKey(), cap);
906                                 });
907                         });
908                         return allCalculatedCap;
909                 }
910                 return null;
911         }
912
913         /**
914          * Prepares a map of requirements lists
915          * Produces a deep copy of the received map of requirements
916          * Sets values to the specific fields according to received component instance 
917          * @param requirements
918          * @param componentInstance
919          * @return
920          */
921         public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
922                 if (requirements != null) {
923                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
924
925                         requirements.entrySet().forEach(e -> {
926                                 List<RequirementDataDefinition> listRequirements = e.getValue().getListToscaDataDefinition().stream().map(r -> new RequirementDataDefinition(r)).collect(Collectors.toList());
927                                 listRequirements.forEach(req -> {
928                                         req.setSource(componentInstance.getComponentUid());
929                                         req.addToPath(componentInstance.getUniqueId());
930                                         req.setOwnerId(componentInstance.getUniqueId());
931                                         req.setOwnerName(componentInstance.getName());
932                                         req.setLeftOccurrences(req.getMaxOccurrences());
933                                         allCalculatedReq.add(e.getKey(), req);
934                                 });
935                         });
936                         return allCalculatedReq;
937                 }
938                 return null;
939         }
940
941         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstanceDataDefinition componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
942
943                 StorageOperationStatus result = null;
944                 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
945                 if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
946                         for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
947                                 Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
948                                 if (groupOptional.isPresent()) {
949                                         GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition((GroupDataDefinition) groupOptional.get(), (ComponentInstanceDataDefinition) componentInstance, null);
950                                         groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(a -> a.getUniqueId()).collect(Collectors.toList()));
951                                         groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(a -> a.getArtifactUUID()).collect(Collectors.toList()));
952                                         groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
953                                 }
954                         }
955                 }
956                 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
957                         result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
958                 }
959                 if (result == null) {
960                         result = StorageOperationStatus.OK;
961                 }
962                 return result;
963         }
964
965         private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
966                 String ciOriginComponentUid = resourceInstance.getComponentUid();
967
968                 if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
969                         resourceInstance.setCustomizationUUID(generateCustomizationUUID());
970                 }
971                 ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
972
973                 Long creationDate = resourceInstance.getCreationTime();
974                 Long modificationTime;
975                 if (creationDate == null) {
976                         creationDate = System.currentTimeMillis();
977                         modificationTime = creationDate;
978                 } else {
979                         modificationTime = System.currentTimeMillis();
980                 }
981                 dataDefinition.setComponentUid(ciOriginComponentUid);
982                 dataDefinition.setCreationTime(creationDate);
983                 dataDefinition.setModificationTime(modificationTime);
984                 if (StringUtils.isNotEmpty(instanceNewName)) {
985                         dataDefinition.setName(instanceNewName);
986                         resourceInstance.setName(instanceNewName);
987                 }
988                 if (StringUtils.isNotEmpty(dataDefinition.getName()))
989                         dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
990                 dataDefinition.setIcon(resourceInstance.getIcon());
991                 if (generateUid) {
992                         dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
993                         resourceInstance.setUniqueId(dataDefinition.getUniqueId());
994                 }
995                 if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
996                         dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
997                 if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
998                         dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
999                 if (originToscaElement != null && dataDefinition.getToscaComponentName() == null)
1000                         dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
1001                 if (dataDefinition.getOriginType() == null && originToscaElement != null) {
1002                         ResourceTypeEnum resourceType = originToscaElement.getResourceType();
1003                         OriginTypeEnum originType = null;
1004                         switch (resourceType) {
1005                         case VF:
1006                                 originType = OriginTypeEnum.VF;
1007                                 break;
1008                         case VFC:
1009                                 originType = OriginTypeEnum.VFC;
1010                                 break;
1011                         case CVFC:
1012                                 originType = OriginTypeEnum.CVFC;
1013                                 break;
1014                         case VL:
1015                                 originType = OriginTypeEnum.VL;
1016                                 break;
1017                         case CP:
1018                                 originType = OriginTypeEnum.CP;
1019                                 break;
1020                         case PNF:
1021                                 originType = OriginTypeEnum.PNF;
1022                                 break;
1023                         case ServiceProxy:
1024                                 originType = OriginTypeEnum.ServiceProxy;
1025                                 break;
1026                         case Configuration:
1027                                 originType = OriginTypeEnum.Configuration;
1028                                 break;
1029                         default:
1030                                 break;
1031                         }
1032                         dataDefinition.setOriginType(originType);
1033                 }
1034                 if(dataDefinition.getOriginType()  == OriginTypeEnum.ServiceProxy)
1035                         dataDefinition.setIsProxy(true);
1036         
1037                 return dataDefinition;
1038         }
1039
1040         private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
1041                 Boolean isUniqueName = true;
1042                 try {
1043                         isUniqueName = !container.getComponentInstances().values().stream().filter(ci -> ci.getName() != null && ci.getName().equals(instanceName)).findAny().isPresent();
1044
1045                 } catch (Exception e) {
1046                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
1047                 }
1048                 return isUniqueName;
1049         }
1050
1051         private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
1052                 return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
1053         }
1054
1055         public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef relation) {
1056                 List<RequirementCapabilityRelDef> relations = new ArrayList<>();
1057                 relations.add(relation);
1058                 Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(componentId, relations);
1059                 if (associateResourceInstances.isRight()) {
1060                         return Either.right(associateResourceInstances.right().value());
1061                 }
1062                 return Either.left(associateResourceInstances.left().value().get(0));
1063         }
1064
1065         @SuppressWarnings({ "unchecked" })
1066         public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
1067
1068                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1069                 if (containerVEither.isRight()) {
1070                         TitanOperationStatus error = containerVEither.right().value();
1071                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1072                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1073                 }
1074                 GraphVertex containerV = containerVEither.left().value();
1075                 List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
1076                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1077                 if (capResult.isRight()) {
1078                         return Either.right(capResult.right().value());
1079
1080                 }
1081                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
1082
1083                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1084                 if (capResult.isRight()) {
1085                         return Either.right(capResult.right().value());
1086
1087                 }
1088                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
1089
1090                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1091                 if (reqResult.isRight()) {
1092                         return Either.right(reqResult.right().value());
1093                 }
1094                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1095
1096                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1097                 if (reqResult.isRight()) {
1098                         return Either.right(reqResult.right().value());
1099                 }
1100                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
1101
1102                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1103                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1104
1105                 StorageOperationStatus status;
1106                 List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
1107                 for (RequirementCapabilityRelDef relation : relations) {
1108
1109                         String fromNode = relation.getFromNode();
1110                         String toNode = relation.getToNode();
1111                         List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
1112                         if (relationships == null || relationships.isEmpty()) {
1113                                 BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1114                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
1115                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
1116                         }
1117
1118                         for (CapabilityRequirementRelationship immutablePair : relationships) {
1119                                 String requirement = immutablePair.getRelation().getRequirement();
1120
1121                                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair.getRelation(), calculatedCapabilty, calculatedRequirement, fullFilledCapabilty, fullfilledRequirement,
1122                                                 compositionDataDefinition, containerV.getUniqueId());
1123
1124                                 if (associateRes.isRight()) {
1125                                         status = associateRes.right().value();
1126                                         BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1127                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
1128                                         return Either.right(status);
1129                                 }
1130
1131                                 RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) associateRes.left().value().get(JsonPresentationFields.RELATIONSHIP);
1132                                 RelationshipImpl relationshipImplResult = new RelationshipImpl();
1133                                 relationshipImplResult.setType(relationshipInstData.getType());
1134                                 RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
1135                                 requirementAndRelationshipPair.setCapability(immutablePair.getRelation().getCapability());
1136                                 requirementAndRelationshipPair.setRequirement(immutablePair.getRelation().getRequirement());
1137                                 requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
1138                                 requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
1139                                 requirementAndRelationshipPair.setCapabilityUid(immutablePair.getRelation().getCapabilityUid());
1140                                 requirementAndRelationshipPair.setRequirementUid(immutablePair.getRelation().getRequirementUid());
1141                                 requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
1142                                 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
1143                                 capReqRel.setRelation(requirementAndRelationshipPair);
1144                                 capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPAPILITY));
1145                                 capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
1146                                 relationshipsResult.add(capReqRel);
1147                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
1148                                 status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
1149                                 if (status != StorageOperationStatus.OK) {
1150                                         return Either.right(status);
1151                                 }
1152                                 status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
1153                                 if (status != StorageOperationStatus.OK) {
1154                                         return Either.right(status);
1155                                 }
1156                         }
1157                         RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef();
1158                         capabilityRelDef.setFromNode(fromNode);
1159                         capabilityRelDef.setToNode(toNode);
1160                         capabilityRelDef.setRelationships(relationshipsResult);
1161                         relationsList.add(capabilityRelDef);
1162                 }
1163                 // update metadata of container and composition json
1164                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1165                 if (status != StorageOperationStatus.OK) {
1166                         return Either.right(status);
1167                 }
1168
1169                 return Either.left(relationsList);
1170         }
1171
1172         private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult,
1173                         Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
1174                         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
1175                 containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1176                 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
1177                 if (updateElement.isRight()) {
1178                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
1179                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1180                 }
1181                 // update cap/req jsons, fulfilled cap/req jsons!!!!!
1182                 Either<GraphVertex, TitanOperationStatus> status;
1183                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
1184                 status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1185                 if (status.isRight()) {
1186                         TitanOperationStatus error = status.right().value();
1187                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
1188                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1189                 }
1190
1191                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1192                 status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1193                 if (status.isRight()) {
1194                         TitanOperationStatus error = status.right().value();
1195                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
1196                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1197                 }
1198
1199                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
1200                 status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1201                 if (status.isRight()) {
1202                         TitanOperationStatus error = status.right().value();
1203                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
1204                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1205                 }
1206
1207                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
1208                 status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1209                 if (status.isRight()) {
1210                         TitanOperationStatus error = status.right().value();
1211                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
1212                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1213                 }
1214                 return StorageOperationStatus.OK;
1215         }
1216
1217         @SuppressWarnings({ "unchecked" })
1218         public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
1219                 if (requirementDef.getRelationships() == null) {
1220                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
1221                         return Either.right(StorageOperationStatus.BAD_REQUEST);
1222                 }
1223
1224                 String fromResInstanceUid = requirementDef.getFromNode();
1225                 String toResInstanceUid = requirementDef.getToNode();
1226
1227                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1228                 if (containerVEither.isRight()) {
1229                         TitanOperationStatus error = containerVEither.right().value();
1230                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1231                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1232                 }
1233                 GraphVertex containerV = containerVEither.left().value();
1234
1235                 // DE191707 - validations
1236                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1237                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1238                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1239                 ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
1240                 if (ciFrom == null) {
1241                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
1242                         return Either.right(StorageOperationStatus.NOT_FOUND);
1243
1244                 }
1245                 ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
1246                 if (ciFrom == ciTo) {
1247                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
1248                         return Either.right(StorageOperationStatus.NOT_FOUND);
1249
1250                 }
1251                 Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
1252
1253                 List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
1254                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1255                 if (capResult.isRight()) {
1256                         return Either.right(capResult.right().value());
1257                 }
1258                 Map<String, MapListCapabiltyDataDefinition> calculatedCapability = capResult.left().value().getRight();
1259
1260                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1261                 if (capResult.isRight()) {
1262                         return Either.right(capResult.right().value());
1263
1264                 }
1265                 Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1266
1267                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1268                 if (reqResult.isRight()) {
1269                         return Either.right(reqResult.right().value());
1270                 }
1271                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1272
1273                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1274                 if (reqResult.isRight()) {
1275                         return Either.right(reqResult.right().value());
1276                 }
1277                 Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1278
1279                 for (CapabilityRequirementRelationship relationPair : relationPairList) {
1280                         Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
1281                         boolean isDeleted = false;
1282                         while (iterator.hasNext()) {
1283                                 Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
1284                                 RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
1285                                 if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson.getUniqueId().equals(relationPair.getRelation().getId())) {
1286                                         if (relationPair.getRelation().equalsTo(relationInJson)) {
1287                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(),
1288                                                                 relationInJson.getCapabilityOwnerId(), relationInJson.getRequirementOwnerId());
1289                                                 iterator.remove();
1290
1291                                                 // update calculated cap/req
1292                                                 StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability, toResInstanceUid, relationInJson, relationPair);
1293                                                 if (status != StorageOperationStatus.OK) {
1294                                                         return Either.right(status);
1295                                                 }
1296                                                 status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid, relationInJson, relationPair);
1297                                                 if (status != StorageOperationStatus.OK) {
1298                                                         return Either.right(status);
1299                                                 }
1300                                                 isDeleted = true;
1301                                         }
1302                                 }
1303                         }
1304                         if (!isDeleted) {
1305                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
1306                                                 relationPair.getRelation().getCapabilityOwnerId(), relationPair.getRelation().getRequirementOwnerId());
1307                                 return Either.right(StorageOperationStatus.NOT_FOUND);
1308                         }
1309                 }
1310                 StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
1311                 if (status != StorageOperationStatus.OK) {
1312                         return Either.right(status);
1313                 }
1314                 status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
1315                 if (status != StorageOperationStatus.OK) {
1316                         return Either.right(status);
1317                 }
1318
1319                 // update jsons
1320                 // update metadata of container and composition json
1321                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1322                 if (status != StorageOperationStatus.OK) {
1323                         return Either.right(status);
1324                 }
1325
1326                 return Either.left(requirementDef);
1327         }
1328         
1329         /**
1330          * Retrieves fulfilled requirement according to relation and received predicate
1331          * @param componentId
1332          * @param instanceId
1333          * @param foundRelation
1334          * @param predicate
1335          * @return
1336          */
1337         public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
1338
1339                 Either<RequirementDataDefinition, StorageOperationStatus> result = null;
1340                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
1341                 MapListRequirementDataDefinition reqMapOfLists = null;
1342                 Optional<RequirementDataDefinition> foundRequirement;
1343                 RelationshipInfo relationshipInfo = foundRelation.getSingleRelationship().getRelation();
1344                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1345                 if (containerVEither.isRight()) {
1346                         TitanOperationStatus error = containerVEither.right().value();
1347                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1348                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1349                 }
1350                 if(result == null){
1351                         GraphVertex containerV = containerVEither.left().value();
1352                         reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1353                         if (reqFullResult.isRight()) {
1354                                 result = Either.right(reqFullResult.right().value());
1355                         }
1356                 }
1357                 if(result == null){
1358                         Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1359                         reqMapOfLists = fulfilledRequirement.get(instanceId);   
1360                         if(reqMapOfLists == null){
1361                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1362                         }
1363                 }
1364                 if(result == null && reqMapOfLists != null){
1365                         for(ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()){
1366                                 foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req)).findFirst();
1367                                 if(foundRequirement.isPresent()){
1368                                         result = Either.left(foundRequirement.get());
1369                                 }
1370                         }
1371                 }
1372                 return result;
1373         }
1374         
1375         /**
1376          * Retrieves fulfilled capability according to relation and received predicate
1377          * @param componentId
1378          * @param instanceId
1379          * @param foundRelation
1380          * @param predicate
1381          * @return
1382          */
1383         public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation, BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
1384                 
1385                 Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
1386                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = null;
1387                 MapListCapabiltyDataDefinition capMapOfLists = null;
1388                 Optional<CapabilityDataDefinition> foundRequirement;
1389                 
1390                 RelationshipInfo relationshipInfo = foundRelation.getSingleRelationship().getRelation();
1391                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1392                 if (containerVEither.isRight()) {
1393                         TitanOperationStatus error = containerVEither.right().value();
1394                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1395                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1396                 }
1397                 if(result == null){
1398                         GraphVertex containerV = containerVEither.left().value();
1399                         capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1400                         if (capFullResult.isRight()) {
1401                                 result = Either.right(capFullResult.right().value());
1402                         }
1403                 }
1404                 if(result == null){
1405                         Map<String, MapListCapabiltyDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1406                         capMapOfLists = fulfilledCapability.get(instanceId);
1407                         if(capMapOfLists == null){
1408                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1409                         }
1410                 }
1411                 if(result == null && capMapOfLists != null){
1412                         for(ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()){
1413                                 foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap)).findFirst();
1414                                 if(foundRequirement.isPresent()){
1415                                         result = Either.left(foundRequirement.get());
1416                                 }
1417                         }
1418                 }
1419                 return result;
1420         }
1421
1422         private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1423                         RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1424                 StorageOperationStatus status;
1425                 String hereIsTheKey = null;
1426                 MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
1427                 if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
1428                         // move from fulfilled
1429                         status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1430                 } else {
1431                         hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1432                         ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1433                         Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
1434                                         .filter(req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())).findFirst();
1435
1436                         if (requirementOptional.isPresent()) {
1437
1438                                 RequirementDataDefinition requirement = requirementOptional.get();
1439                                 String leftOccurrences = requirement.getLeftOccurrences();
1440                                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1441                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1442                                         ++leftIntValue;
1443                                         requirement.setLeftOccurrences(String.valueOf(leftIntValue));
1444                                 }
1445                                 if(relationship != null){
1446                                         relationship.setRequirement(requirement);
1447                                 }
1448                                 status = StorageOperationStatus.OK;
1449                         } else {
1450                                 // move from fulfilled
1451                                 status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1452                         }
1453                 }
1454                 return status;
1455         }
1456
1457         private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
1458                         RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1459                 StorageOperationStatus status;
1460                 String hereIsTheKey = null;
1461                 MapListCapabiltyDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
1462                 if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
1463                         // move from fulfilled
1464                         status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1465                 } else {
1466                         hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1467                         ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1468                         Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream().filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
1469                                         .findFirst();
1470
1471                         if (capabilityOptional.isPresent()) {
1472
1473                                 CapabilityDataDefinition capability = capabilityOptional.get();
1474                                 String leftOccurrences = capability.getLeftOccurrences();
1475                                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1476                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1477                                         ++leftIntValue;
1478                                         capability.setLeftOccurrences(String.valueOf(leftIntValue));
1479                                 }
1480                                 if(relationship != null){
1481                                         relationship.setCapability(capability);
1482                                 }
1483                                 status = StorageOperationStatus.OK;
1484                         } else {
1485                                 // move from fulfilled
1486                                 status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1487                         }
1488                 }
1489                 return status;
1490         }
1491
1492         private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabiltyDataDefinition> calculatedCapability, Map<String, MapListCapabiltyDataDefinition> fullFilledCapability, String toResInstanceUid,
1493                         RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1494                 MapListCapabiltyDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
1495                 if (capByInstance == null) {
1496                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
1497                         return StorageOperationStatus.GENERAL_ERROR;
1498                 }
1499                 if (null == hereIsTheKey)
1500                         hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1501                 if (null == hereIsTheKey) {
1502                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(), toResInstanceUid);
1503                         return StorageOperationStatus.GENERAL_ERROR;
1504                 }
1505                 ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1506                 Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
1507                 boolean found = false;
1508                 while (iterator.hasNext()) {
1509                         CapabilityDataDefinition cap = iterator.next();
1510                         if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
1511                                 found = true;
1512                                 iterator.remove();
1513                                 // return to calculated list
1514                                 String leftOccurrences = cap.getLeftOccurrences();
1515                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1516                                 ++leftIntValue;
1517                                 cap.setLeftOccurrences(String.valueOf(leftIntValue));
1518
1519                                 MapListCapabiltyDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
1520                                 if (mapListCapaDataDef == null) {
1521                                         mapListCapaDataDef = new MapListCapabiltyDataDefinition();
1522                                 }
1523                                 ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
1524                                 if (findByKey == null) {
1525                                         findByKey = new ListCapabilityDataDefinition();
1526                                         mapListCapaDataDef.put(hereIsTheKey, findByKey);
1527                                 }
1528                                 findByKey.add(cap);
1529                                 relationship.setCapability(cap);
1530                                 break;
1531                         }
1532                 }
1533                 if (found == false) {
1534                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getCapabilityOwnerId(), toResInstanceUid);
1535                         return StorageOperationStatus.GENERAL_ERROR;
1536                 }
1537                 return StorageOperationStatus.OK;
1538         }
1539
1540         private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1541                         RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1542                 MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
1543                 if (reqByInstance == null) {
1544                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
1545                         return StorageOperationStatus.GENERAL_ERROR;
1546                 }
1547                 if (null == hereIsTheKey)
1548                         hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1549                 if (null == hereIsTheKey) {
1550                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(), fromResInstanceUid);
1551                         return StorageOperationStatus.GENERAL_ERROR;
1552                 }
1553                 ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1554                 Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
1555                 boolean found = false;
1556                 while (iterator.hasNext()) {
1557                         RequirementDataDefinition req = iterator.next();
1558                         if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
1559                                 found = true;
1560                                 iterator.remove();
1561                                 // return to calculated list
1562                                 String leftOccurrences = req.getLeftOccurrences();
1563                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1564                                 ++leftIntValue;
1565                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1566
1567                                 MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
1568                                 if (mapListReqDataDef == null) {
1569                                         mapListReqDataDef = new MapListRequirementDataDefinition();
1570                                 }
1571                                 ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
1572                                 if (findByKey == null) {
1573                                         findByKey = new ListRequirementDataDefinition();
1574                                         mapListReqDataDef.put(hereIsTheKey, findByKey);
1575                                 }
1576                                 findByKey.add(req);
1577                                 relationship.setRequirement(req);
1578                                 break;
1579                         }
1580                 }
1581                 if (found == false) {
1582                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getRequirementOwnerId(), fromResInstanceUid);
1583                         return StorageOperationStatus.GENERAL_ERROR;
1584                 }
1585                 return StorageOperationStatus.OK;
1586
1587         }
1588
1589         public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
1590                 ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
1591
1592                 if (componentInstance == null) {
1593                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
1594                         return StorageOperationStatus.NOT_FOUND;
1595                 }
1596                 UUID uuid = UUID.randomUUID();
1597                 componentInstance.setCustomizationUUID(uuid.toString());
1598
1599                 return StorageOperationStatus.OK;
1600         }
1601
1602         public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair,
1603                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1604                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
1605                 String requirement = relationPair.getRequirement();
1606                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1607
1608                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
1609
1610                 ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
1611                 if (fromResourceInstData == null) {
1612                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
1613                         return Either.right(StorageOperationStatus.NOT_FOUND);
1614                 }
1615                 ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
1616                 if (toResourceInstData == null) {
1617                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
1618                         return Either.right(StorageOperationStatus.NOT_FOUND);
1619                 }
1620
1621                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
1622                                 fullfilledRequirement, containerId);
1623                 if (reqVsCap.isRight()) {
1624                         StorageOperationStatus status = reqVsCap.right().value();
1625                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
1626                         return Either.right(status);
1627                 }
1628                 Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
1629
1630                 // add to json new relations
1631                 compositionDataDefinition.addRelation(((RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(), (RelationshipInstDataDefinition)relationship.get(JsonPresentationFields.RELATIONSHIP));
1632
1633                 return Either.left(relationship);
1634         }
1635
1636         private Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
1637
1638                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, TitanOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
1639                 if (calculatedCapabiltyEither.isRight()) {
1640                         TitanOperationStatus error = calculatedCapabiltyEither.right().value();
1641                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
1642                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1643                 }
1644                 Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
1645                 return Either.left(calculatedCapabilty);
1646         }
1647
1648         private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
1649                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, TitanOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
1650                 if (calculatedRequirementEither.isRight()) {
1651                         TitanOperationStatus error = calculatedRequirementEither.right().value();
1652                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
1653                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1654                 }
1655                 Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
1656                 return Either.left(calculatedRequirement);
1657         }
1658
1659         @SuppressWarnings("unchecked")
1660         private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance, RelationshipInfo relationPair,
1661                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1662                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
1663                 String type = relationPair.getRelationship().getType();
1664                 // capability
1665
1666                 String toInstId = toResInstance.getUniqueId();
1667                 MapListCapabiltyDataDefinition mapListCapabiltyDataDefinition = calculatedCapabilty.get(toInstId);
1668                 Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
1669
1670                 if (mapListCapabiltyDataDefinition == null) {
1671                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
1672                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1673                 }
1674                 ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabiltyDataDefinition.getMapToscaDataDefinition().get(type);
1675                 if (listCapabilityDataDefinition == null) {
1676                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
1677                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1678                 }
1679                 CapabilityDataDefinition capabilityForRelation = null;
1680                 Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
1681                 while (iteratorCap.hasNext()) {
1682                         CapabilityDataDefinition cap = iteratorCap.next();
1683                         if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
1684                                 capabilityForRelation = cap;
1685                                 capReqRelationship.put(JsonPresentationFields.CAPAPILITY, (T)capabilityForRelation);
1686                                 String leftOccurrences = cap.getLeftOccurrences();
1687                                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1688                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1689                                         if (leftIntValue > 0) {
1690                                                 --leftIntValue;
1691                                                 capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
1692                                                 if (leftIntValue == 0) {
1693                                                         // remove from calculated
1694                                                         iteratorCap.remove();
1695                                                         // move to fulfilled
1696                                                         MapListCapabiltyDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
1697                                                         if (mapListCapabiltyFullFilledInst == null) {
1698                                                                 mapListCapabiltyFullFilledInst = new MapListCapabiltyDataDefinition();
1699                                                                 fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
1700                                                         }
1701
1702                                                         ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
1703                                                         if (listCapabilityFull == null) {
1704                                                                 listCapabilityFull = new ListCapabilityDataDefinition();
1705                                                                 mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
1706                                                         }
1707                                                         listCapabilityFull.add(capabilityForRelation);
1708                                                 }
1709                                                 break;
1710                                         } else {
1711                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabilityForRelation.getType(), toInstId, containerId);
1712                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1713                                         }
1714                                 }
1715                         }
1716                 }
1717                 if (capabilityForRelation == null) {
1718                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
1719                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1720                 }
1721
1722                 // requirements
1723                 String fromInstId = fromResInstance.getUniqueId();
1724                 MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
1725                 if (mapListRequirementDataDefinition == null) {
1726                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
1727                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1728                 }
1729                 ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
1730                 if (listRequirementDataDefinition == null) {
1731                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
1732                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1733                 }
1734
1735                 RequirementDataDefinition requirementForRelation = null;
1736                 Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
1737                 while (iteratorReq.hasNext()) {
1738                         RequirementDataDefinition req = iteratorReq.next();
1739                         if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
1740                                 requirementForRelation = req;
1741                                 capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T)requirementForRelation);
1742                                 String leftOccurrences = req.getLeftOccurrences();
1743                                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1744                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1745                                         if (leftIntValue > 0) {
1746                                                 --leftIntValue;
1747                                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1748                                                 if (leftIntValue == 0) {
1749                                                         // remove from calculated
1750                                                         iteratorReq.remove();
1751                                                         // move to fulfilled
1752                                                         MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
1753                                                         if (mapListRequirementFullFilledInst == null) {
1754                                                                 mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
1755                                                                 fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
1756                                                         }
1757
1758                                                         ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
1759                                                         if (listRequirementFull == null) {
1760                                                                 listRequirementFull = new ListRequirementDataDefinition();
1761                                                                 mapListRequirementFullFilledInst.put(type, listRequirementFull);
1762                                                         }
1763                                                         listRequirementFull.add(requirementForRelation);
1764                                                 }
1765                                                 break;
1766                                         } else {
1767                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
1768                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1769                                         }
1770                                 }
1771                         }
1772                 }
1773                 if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
1774                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No math for capability from type {} and requirement {} from {} to {} in container {}.", capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId,
1775                                         toInstId, containerId);
1776                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1777                 }
1778
1779                 RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair);
1780                 if(requirementForRelation.getRelationship() != null)
1781                         relationshipTypeData.setType(requirementForRelation.getRelationship());
1782                 capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T)relationshipTypeData);
1783                 return Either.left(capReqRelationship);
1784         }
1785
1786         private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair) {
1787
1788                 RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
1789                 relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
1790
1791                 relationshipInstData.setType(relationPair.getRelationship().getType());
1792                 Long creationDate = System.currentTimeMillis();
1793                 relationshipInstData.setCreationTime(creationDate);
1794                 relationshipInstData.setModificationTime(creationDate);
1795                 relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
1796                 relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
1797                 relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
1798                 relationshipInstData.setRequirementId(relationPair.getRequirementUid());
1799                 relationshipInstData.setFromId(fromResInstanceUid);
1800                 relationshipInstData.setToId(toInstId);
1801                 relationshipInstData.setRequirement(relationPair.getRequirement());
1802                 relationshipInstData.setCapability(relationPair.getCapability());
1803
1804                 return relationshipInstData;
1805         }
1806
1807         public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
1808
1809                 StorageOperationStatus result = null;
1810                 String containerId = containerComponent.getUniqueId();
1811                 Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
1812                 Either<GraphVertex, TitanOperationStatus> updateElement = null;
1813                 if (!validateInstanceNames(resourcesInstancesMap)) {
1814                         result = StorageOperationStatus.INCONSISTENCY;
1815                 }
1816                 if (result == null) {
1817                         if (!validateInstanceNames(resourcesInstancesMap)) {
1818                                 result = StorageOperationStatus.INCONSISTENCY;
1819                         }
1820                 }
1821                 if (result == null && !allowDeleted) {
1822                         if (!validateDeletedResources(resourcesInstancesMap)) {
1823                                 result = StorageOperationStatus.INCONSISTENCY;
1824                         }
1825                 }
1826                 if (result == null) {
1827                         instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
1828                 }
1829                 if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
1830                         containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1831                         Map<String, CompositionDataDefinition> compositions = new HashMap<>();
1832                         CompositionDataDefinition composition = new CompositionDataDefinition();
1833                         composition.setComponentInstances(instancesJsonData);
1834                         compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
1835                         containerVertex.setJson(compositions);
1836                         updateElement = titanDao.updateVertex(containerVertex);
1837                         if (updateElement.isRight()) {
1838                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
1839                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1840                         }
1841                 }
1842                 if (result == null) {
1843                         result = StorageOperationStatus.OK;
1844                 }
1845                 return result;
1846         }
1847
1848         private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
1849
1850                 Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
1851                 for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
1852                         ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
1853                         instances.put(instance.getUniqueId(), instance);
1854                 }
1855                 return instances;
1856         }
1857
1858         private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1859                 boolean result = true;
1860                 for (Resource resource : resourcesInstancesMap.values()) {
1861                         if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
1862                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
1863                                 result = false;
1864                                 break;
1865                         }
1866                 }
1867                 return result;
1868         }
1869
1870         private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1871                 boolean result = true;
1872                 Set<String> names = new HashSet<>();
1873                 for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
1874                         if (StringUtils.isEmpty(instance.getName())) {
1875                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
1876                                 result = false;
1877                                 break;
1878                         } else if (names.contains(instance.getName())) {
1879                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ", instance.getName());
1880                                 result = false;
1881                                 break;
1882                         } else {
1883                                 names.add(instance.getName());
1884                         }
1885                 }
1886                 return result;
1887         }
1888
1889         public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
1890                 return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
1891         }
1892
1893         public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
1894                 return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS);
1895         }
1896
1897         public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexType) {
1898                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
1899                 if (metadataVertex.isRight()) {
1900                         TitanOperationStatus status = metadataVertex.right().value();
1901                         if (status == TitanOperationStatus.NOT_FOUND) {
1902                                 status = TitanOperationStatus.INVALID_ID;
1903                         }
1904                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1905                 }
1906                 MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
1907                 return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
1908
1909         }
1910
1911         @SuppressWarnings({ "unchecked" })
1912         public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
1913                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1914                 if (metadataVertex.isRight()) {
1915                         TitanOperationStatus status = metadataVertex.right().value();
1916                         if (status == TitanOperationStatus.NOT_FOUND) {
1917                                 status = TitanOperationStatus.INVALID_ID;
1918                         }
1919                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1920                 }
1921                 GraphVertex metaVertex = metadataVertex.left().value();
1922                 Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
1923                 CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1924                 StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
1925                 if (status != StorageOperationStatus.OK) {
1926                         logger.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
1927                         return status;
1928                 }
1929                 Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(metaVertex);
1930                 if (updateVertex.isRight()) {
1931                         logger.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
1932                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
1933                 }
1934                 return StorageOperationStatus.OK;
1935         }
1936
1937         public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
1938                 if (groupInstances != null) {
1939                         Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
1940                         if (dataFromGraph.isRight()) {
1941                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
1942                         }
1943                         MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
1944                         if (grInstPerInstance == null) {
1945                                 logger.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
1946                                 return StorageOperationStatus.NOT_FOUND;
1947                         }
1948                         for (String instGroupForUpdate : groupInstances) {
1949                                 GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
1950                                 if (groupInst == null) {
1951                                         logger.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
1952                                         continue;
1953                                 }
1954                                 UUID uuid = UUID.randomUUID();
1955                                 groupInst.setCustomizationUUID(uuid.toString());
1956                         }
1957
1958                 }
1959                 return StorageOperationStatus.OK;
1960         }
1961
1962         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
1963
1964                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
1965                                 new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(gi -> gi.getName(), gi -> gi))), componentInstance.getUniqueId());
1966         }
1967
1968         public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
1969
1970                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
1971                                 componentInstance.getUniqueId());
1972         }
1973
1974         public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1975
1976                 List<String> pathKeys = new ArrayList<>();
1977                 pathKeys.add(componentInstanceId);
1978                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1979         }
1980
1981         public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, String capabilityUniqueId, ComponentInstanceProperty property) {
1982                 List<String> pathKeys = new ArrayList<>();
1983                 pathKeys.add(componentInstanceId);
1984                 pathKeys.add(capabilityUniqueId);
1985                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1986         }
1987
1988         public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1989                 List<String> pathKeys = new ArrayList<>();
1990                 pathKeys.add(componentInstanceId);
1991                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1992         }
1993
1994         public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
1995                 List<String> pathKeys = new ArrayList<>();
1996                 pathKeys.add(componentInstanceId);
1997                 return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
1998         }
1999
2000         public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2001
2002                 List<String> pathKeys = new ArrayList<>();
2003                 pathKeys.add(componentInstanceId);
2004                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
2005         }
2006
2007         public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) {
2008                 List<String> pathKeys = new ArrayList<>();
2009                 pathKeys.add(componentInstanceId);
2010                 return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME);
2011         }
2012
2013         public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2014                 List<String> pathKeys = new ArrayList<>();
2015                 pathKeys.add(componentInstanceId);
2016                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
2017         }
2018
2019 }