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