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