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