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