a20f85ad7bbc687dc94213c12d7b25e8781451fb
[sdc.git] /
1 package org.openecomp.sdc.be.model.jsontitan.operations;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Map.Entry;
10 import java.util.Optional;
11 import java.util.Set;
12 import java.util.UUID;
13 import java.util.stream.Collectors;
14
15 import org.apache.commons.collections.CollectionUtils;
16 import org.apache.commons.collections.MapUtils;
17 import org.apache.commons.lang.StringUtils;
18 import org.apache.commons.lang3.tuple.ImmutablePair;
19 import org.apache.commons.lang3.tuple.Pair;
20 import org.apache.tinkerpop.gremlin.structure.Direction;
21 import org.apache.tinkerpop.gremlin.structure.Edge;
22 import org.openecomp.sdc.be.config.BeEcompErrorManager;
23 import org.openecomp.sdc.be.config.ConfigurationManager;
24 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
25 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
26 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
27 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
28 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
29 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
30 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
31 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
32 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.MapAttributesDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
39 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
43 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
44 import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
46 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
47 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
48 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
49 import org.openecomp.sdc.be.model.ArtifactDefinition;
50 import org.openecomp.sdc.be.model.CapabilityDefinition;
51 import org.openecomp.sdc.be.model.Component;
52 import org.openecomp.sdc.be.model.ComponentInstance;
53 import org.openecomp.sdc.be.model.ComponentInstanceInput;
54 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
55 import org.openecomp.sdc.be.model.DistributionStatusEnum;
56 import org.openecomp.sdc.be.model.GroupDefinition;
57 import org.openecomp.sdc.be.model.GroupInstance;
58 import org.openecomp.sdc.be.model.RelationshipImpl;
59 import org.openecomp.sdc.be.model.RequirementAndRelationshipPair;
60 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
61 import org.openecomp.sdc.be.model.Resource;
62 import org.openecomp.sdc.be.model.User;
63 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
64 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
65 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
66 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
67 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
68 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
69 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
70 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
71 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
72 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
73 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
74 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
75 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
76 import org.openecomp.sdc.common.util.ValidationUtils;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 import fj.data.Either;
81
82 @org.springframework.stereotype.Component("node-template-operation")
83 public class NodeTemplateOperation extends BaseOperation {
84         private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
85         private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
86         private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
87         public static final String HEAT_ENV_NAME = "heatEnv";
88         public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
89         public static final String HEAT_ENV_SUFFIX = "env";
90         private static Integer defaultHeatTimeout;
91         public static final Integer NON_HEAT_TIMEOUT = 0;
92
93         private static Logger logger = LoggerFactory.getLogger(NodeTemplateOperation.class.getName());
94
95         public NodeTemplateOperation() {
96                 defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes();
97                 if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) {
98                         defaultHeatTimeout = 60;
99                 }
100         }
101
102         public static Integer getDefaultHeatTimeout() {
103                 return defaultHeatTimeout;
104         }
105
106         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, String instanceNumberSuffix, ComponentInstance componentInstance,
107                         boolean allowDeleted, User user) {
108
109                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
110                 Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceRes = null;
111                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to create component instance {} in component {}", componentInstance, container.getUniqueId());
112                 ComponentInstanceDataDefinition componentInstanceData = null;
113                 Either<String, StorageOperationStatus> newInstanceNameRes = null;
114
115                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseJson);
116                 if (metadataVertex.isRight()) {
117                         TitanOperationStatus status = metadataVertex.right().value();
118                         if (status == TitanOperationStatus.NOT_FOUND) {
119                                 status = TitanOperationStatus.INVALID_ID;
120                         }
121                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
122                 }
123
124                 if (result == null) {
125                         newInstanceNameRes = buildValidateInstanceName(container, originToscaElement, componentInstance, instanceNumberSuffix);
126                         if (newInstanceNameRes.isRight()) {
127                                 result = Either.right(newInstanceNameRes.right().value());
128                         }
129                 }
130                 if (result == null) {
131                         componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), newInstanceNameRes.left().value(), true, originToscaElement);
132
133                         addComponentInstanceRes = addComponentInstanceToTopologyTemplate(container, originToscaElement, componentInstanceData, metadataVertex.left().value(), allowDeleted, user);
134
135                         if (addComponentInstanceRes.isRight()) {
136                                 StorageOperationStatus status = addComponentInstanceRes.right().value();
137                                 if (status == StorageOperationStatus.NOT_FOUND) {
138                                         status = StorageOperationStatus.INVALID_ID;
139                                 }
140                                 result = Either.right(status);
141                         }
142                 }
143                 if (result == null) {
144                         result = Either.left(new ImmutablePair<>(addComponentInstanceRes.left().value(), componentInstanceData.getUniqueId()));
145                 }
146                 return result;
147         }
148
149         private Either<String, StorageOperationStatus> buildValidateInstanceName(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance, String instanceNumberSuffix) {
150
151                 Either<String, StorageOperationStatus> result = null;
152                 String instanceName = componentInstance.getName();
153                 if (StringUtils.isEmpty(instanceName) || instanceName.equalsIgnoreCase(originToscaElement.getName())) {
154                         instanceName = buildComponentInstanceName(instanceNumberSuffix, instanceName);
155                 } else if (!isUniqueInstanceName(container, componentInstance.getName())) {
156                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create component instance with name {} on component container {}. The instance with the same name already exists. ", componentInstance.getName(), container.getName());
157                         result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
158                 }
159                 if (result == null) {
160                         result = Either.left(instanceName);
161                 }
162                 return result;
163         }
164
165         public Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex metadataVertex,
166                         boolean allowDeleted, User user) {
167
168                 Either<TopologyTemplate, StorageOperationStatus> result = null;
169                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
170                 String containerComponentId = container.getUniqueId();
171                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to create component instance {} in component {}", componentInstance, containerComponentId);
172                 String instOriginComponentId = componentInstance.getComponentUid();
173                 Either<GraphVertex, TitanOperationStatus> updateElement = null;
174
175                 Boolean isDeleted = (Boolean) originToscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED);
176
177                 if (!allowDeleted && (isDeleted != null) && isDeleted) {
178                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance", instOriginComponentId);
179                         result = Either.right(StorageOperationStatus.INVALID_ID);
180                 }
181                 if (result == null) {
182                         container.addComponentInstance(componentInstance);
183                         metadataVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
184                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex, container, JsonParseFlagEnum.ParseAll);
185                         updateElement = titanDao.updateVertex(metadataVertex);
186                         if (updateElement.isRight()) {
187                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
188                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
189                         }
190                 }
191                 if (result == null) {
192                         Either<GraphVertex, StorageOperationStatus> addToscaDataRes = addComponentInstanceToscaDataToContainerComponent(originToscaElement, componentInstance, updateElement.left().value(), user);
193                         if (addToscaDataRes.isRight()) {
194                                 result = Either.right(addToscaDataRes.right().value());
195                         }
196                 }
197
198                 if (result == null) {
199                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
200                         if (updateContainerComponentRes.isRight()) {
201                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
202                                 result = Either.right(updateContainerComponentRes.right().value());
203                         }
204                 }
205                 if (result == null) {
206                         result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
207                 }
208                 return result;
209         }
210
211         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance) {
212
213                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
214                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
215
216                 String containerComponentId = container.getUniqueId();
217                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstance, containerComponentId);
218                 ComponentInstanceDataDefinition componentInstanceData = null;
219
220                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
221                 if (metadataVertex.isRight()) {
222                         TitanOperationStatus status = metadataVertex.right().value();
223                         if (status == TitanOperationStatus.NOT_FOUND) {
224                                 status = TitanOperationStatus.INVALID_ID;
225                         }
226                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
227                 }
228                 if (result == null) {
229                         componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), componentInstance.getName(), false, originToscaElement);
230                         container.addComponentInstance(componentInstanceData);
231                         metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
232                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
233                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
234                         if (updateElement.isRight()) {
235                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstance.getName());
236                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
237                         }
238                 }
239                 if (result == null) {
240                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
241                         if (updateContainerComponentRes.isRight()) {
242                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ", container.getName(), componentInstance.getName());
243                                 result = Either.right(updateContainerComponentRes.right().value());
244                         }
245                 }
246                 if (result == null) {
247                         result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceData.getUniqueId()));
248                 }
249                 return result;
250         }
251
252         public Either<TopologyTemplate, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container) {
253
254                 Either<TopologyTemplate, StorageOperationStatus> result = null;
255                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
256
257                 String containerComponentId = container.getUniqueId();
258                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata  of container component {}", containerComponentId);
259
260                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
261                 if (metadataVertex.isRight()) {
262                         TitanOperationStatus status = metadataVertex.right().value();
263                         if (status == TitanOperationStatus.NOT_FOUND) {
264                                 status = TitanOperationStatus.INVALID_ID;
265                         }
266                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
267                 }
268                 if (result == null) {
269                         metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
270                         topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
271                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(metadataVertex.left().value());
272                         if (updateElement.isRight()) {
273                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {}. ", container.getName());
274                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
275                         }
276                 }
277                 if (result == null) {
278                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
279                         if (updateContainerComponentRes.isRight()) {
280                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {}. ", container.getName());
281                                 result = Either.right(updateContainerComponentRes.right().value());
282                         }
283                 }
284                 if (result == null) {
285                         result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
286                 }
287                 return result;
288         }
289
290         public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(TopologyTemplate container, String componentInstanceId) {
291
292                 Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
293                 Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
294
295                 String containerComponentId = container.getUniqueId();
296                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstanceId, containerComponentId);
297
298                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
299                 if (metadataVertex.isRight()) {
300                         TitanOperationStatus status = metadataVertex.right().value();
301                         if (status == TitanOperationStatus.NOT_FOUND) {
302                                 status = TitanOperationStatus.INVALID_ID;
303                         }
304                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
305                 }
306                 GraphVertex containerV = null;
307                 if (result == null) {
308                         container.getComponentInstances().remove(componentInstanceId);
309                         containerV = metadataVertex.left().value();
310                         StorageOperationStatus status = removeRelationsOfInstance(container, componentInstanceId, containerV);
311                         if (status != StorageOperationStatus.OK) {
312                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete relation for component instance {} in container. error {}", componentInstanceId, container.getUniqueId(), status);
313                                 result = Either.right(status);
314                         }
315
316                         containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
317                         topologyTemplateOperation.fillToscaElementVertexData(containerV, container, JsonParseFlagEnum.ParseAll);
318                         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
319                         if (updateElement.isRight()) {
320                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instance {}. ", container.getName(), componentInstanceId);
321                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
322                         }
323                 }
324                 if (result == null) {
325                         StorageOperationStatus status = deleteComponentInstanceToscaDataFromContainerComponent(containerV, componentInstanceId);
326                         if (status != StorageOperationStatus.OK) {
327                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete data  for instance {} in container {}. error {] ", componentInstanceId, container.getUniqueId(), status);
328                                 return Either.right(status);
329                         }
330                         updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
331                         if (updateContainerComponentRes.isRight()) {
332                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} after deleting the component instance {}. ", container.getName(), componentInstanceId);
333                                 result = Either.right(updateContainerComponentRes.right().value());
334                         }
335                 }
336                 if (result == null) {
337                         result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceId));
338                 }
339                 return result;
340         }
341
342         private StorageOperationStatus removeRelationsOfInstance(TopologyTemplate container, String ciToRemove, GraphVertex containerV) {
343                 CompositionDataDefinition composition = container.getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue());
344                 if (composition != null) {
345                         Map<String, RelationshipInstDataDefinition> relations = composition.getRelations();
346                         if (relations != null) {
347                                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
348                                 if (capResult.isRight()) {
349                                         return capResult.right().value();
350
351                                 }
352                                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
353
354                                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
355                                 if (capResult.isRight()) {
356                                         return capResult.right().value();
357
358                                 }
359                                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
360
361                                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
362                                 if (reqResult.isRight()) {
363                                         return reqResult.right().value();
364                                 }
365                                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
366
367                                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
368                                 if (reqResult.isRight()) {
369                                         return reqResult.right().value();
370                                 }
371                                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
372
373                                 Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
374                                 while (iterator.hasNext()) {
375                                         Entry<String, RelationshipInstDataDefinition> relation = iterator.next();
376                                         RelationshipInstDataDefinition relationToDelete = relation.getValue();
377                                         if (relationToDelete.getFromId().equals(ciToRemove) || relationToDelete.getToId().equals(ciToRemove)) {
378                                                 iterator.remove();
379                                                 if (relationToDelete.getFromId().equals(ciToRemove)) {
380                                                         updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, ciToRemove, relationToDelete);
381                                                         updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, relationToDelete.getToId(), relationToDelete);
382                                                 }
383                                                 if (relationToDelete.getToId().equals(ciToRemove)) {
384                                                         updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, relationToDelete.getFromId(), relationToDelete);
385                                                         updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, ciToRemove, relationToDelete);
386                                                 }
387                                         }
388                                 }
389                         }
390                 }
391                 return StorageOperationStatus.OK;
392         }
393
394         private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
395                 StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
396                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
397                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
398                         return status;
399                 }
400                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
401                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
402                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
403                         return status;
404                 }
405                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
406                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
407                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
408                         return status;
409                 }
410                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
411                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
412                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
413                         return status;
414                 }
415                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, componentInstanceId);
416                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
417                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
418                         return status;
419                 }
420                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, componentInstanceId);
421                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
422                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
423                         return status;
424                 }
425                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, componentInstanceId);
426                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
427                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
428                         return status;
429                 }
430                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, componentInstanceId);
431                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
432                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
433                         return status;
434                 }
435                 status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
436                 if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
437                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ", componentInstanceId, containerV.getUniqueId(), status);
438                         return status;
439                 }
440                 return StorageOperationStatus.OK;
441         }
442
443         private Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user) {
444
445                 Either<GraphVertex, StorageOperationStatus> result;
446                 StorageOperationStatus status;
447                 if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NodeType) {
448                         status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex, user, HEAT_VF_ENV_NAME);
449                 } else {
450                         status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance, updatedContainerVertex);
451                 }
452                 if (status == StorageOperationStatus.OK) {
453                         result = Either.left(updatedContainerVertex);
454                 } else {
455                         result = Either.right(status);
456                 }
457                 return result;
458         }
459
460         private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
461
462                 StorageOperationStatus status;
463
464                 status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
465
466                 if (status != StorageOperationStatus.OK) {
467
468                         return status;
469                 }
470
471                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
472
473                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, instProperties, componentInstance.getUniqueId());
474                 if (status != StorageOperationStatus.OK) {
475                         return status;
476                 }
477
478                 return status;
479         }
480
481         private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
482                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
483
484                 if (calculatedCapabilities != null) {
485                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
486                         calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
487                                 Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
488                                 mapByType.entrySet().forEach(entryPerType -> {
489                                         entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
490                                                 cap.addToPath(componentInstance.getUniqueId());
491                                                 allCalculatedCap.add(entryPerType.getKey(), cap);
492                                         });
493                                 });
494                         });
495
496                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
497                                         componentInstance.getUniqueId());
498
499                         if (calculatedResult != StorageOperationStatus.OK) {
500                                 return calculatedResult;
501                         }
502                         MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
503                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
504
505                         if (calculatedResult != StorageOperationStatus.OK) {
506                                 return calculatedResult;
507                         }
508                 }
509                 Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
510                 if (calculatedRequirements != null) {
511
512                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
513                         calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
514                                 Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
515                                 mapByType.entrySet().forEach(entryPerType -> {
516                                         entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
517                                                 req.addToPath(componentInstance.getUniqueId());
518                                                 allCalculatedReq.add(entryPerType.getKey(), req);
519                                         });
520                                 });
521                         });
522
523                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
524                                         componentInstance.getUniqueId());
525                         if (calculatedResult != StorageOperationStatus.OK) {
526                                 return calculatedResult;
527                         }
528                         MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
529                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
530                         if (calculatedResult != StorageOperationStatus.OK) {
531                                 return calculatedResult;
532                         }
533                 }
534
535                 Map<String, MapCapabiltyProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
536                 Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
537
538                 if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
539                         for (MapCapabiltyProperty map : calculatedCapabilitiesProperties.values()) {
540                                 for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
541                                         String newKey = new String(componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
542                                         updateKeyMap.put(newKey, entry.getValue());
543                                 }
544                         }
545                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
546                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty,
547                                         componentInstance.getUniqueId());
548                         if (calculatedResult != StorageOperationStatus.OK) {
549                                 return calculatedResult;
550                         }
551                 }
552                 return StorageOperationStatus.OK;
553         }
554
555         private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
556
557                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(originNodeType.getProperties());
558
559                 StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
560                 if (status != StorageOperationStatus.OK) {
561                         return status;
562                 }
563
564                 MapAttributesDataDefinition instAttributes = new MapAttributesDataDefinition(originNodeType.getAttributes());
565
566                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
567
568                 if (status != StorageOperationStatus.OK) {
569                         return status;
570                 }
571                 status = addInstanceDeploymentArtifacts(originNodeType, componentInstance, updatedContainerVertex, user, envType);
572                 if (status != StorageOperationStatus.OK) {
573                         return status;
574                 }
575                 return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
576
577         }
578
579         private StorageOperationStatus addInstanceDeploymentArtifacts(ToscaElement originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex, User user, String envType) {
580                 Map<String, ArtifactDataDefinition> deploymentArtifacts = originNodeType.getDeploymentArtifacts();
581                 MapArtifactDataDefinition instArtifacts = prepareInstDeploymentArtifactPerInstance(deploymentArtifacts, componentInstance.getUniqueId(), user, envType);
582                 if (instArtifacts != null) {
583                         StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArtifacts,
584                                         componentInstance.getUniqueId());
585
586                         if (calculatedResult != StorageOperationStatus.OK) {
587                                 return calculatedResult;
588                         }
589                 }
590                 return StorageOperationStatus.OK;
591         }
592
593         public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
594                 if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
595                         Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
596                         deploymentArtifacts.entrySet().forEach(e -> {
597                                 ArtifactDataDefinition artifact = e.getValue();
598                                 String type = artifact.getArtifactType();
599                                 if (!(type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()))) {
600                                         instDeploymentArtifacts.put(e.getKey(), artifact);
601                                         ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
602                                         instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
603                                 }
604                         });
605
606                         MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeploymentArtifacts);
607                         return instArtifacts;
608                 }
609                 return null;
610         }
611
612         @SuppressWarnings({ "unchecked" })
613         private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
614                 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
615                 if (deploymentResourceArtifacts == null) {
616                         logger.debug("no deployment artifacts are configured for generated artifacts");
617                         return null;
618                 }
619                 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
620                 if (placeHolderData == null) {
621                         logger.debug("no env type {} are configured for generated artifacts", heatEnvType);
622                         return null;
623                 }
624
625                 String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
626
627                 ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
628
629                 String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
630                 String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
631                 String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
632
633                 artifactInfo.setArtifactDisplayName(artifactName);
634                 artifactInfo.setArtifactLabel(envLabel);
635                 artifactInfo.setArtifactType(artifactType);
636                 artifactInfo.setDescription(artifactDescription);
637                 artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
638                 setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
639                 artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
640                 // clone heat parameters in case of heat env only not VF heat env
641                 if (heatEnvType.equals(HEAT_ENV_NAME)) {
642                         artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
643                 }
644                 setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
645
646                 return artifactInfo;
647         }
648
649         public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
650                 if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
651                         artifactInfo.setTimeout(defaultHeatTimeout);
652                 } else {
653                         artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
654                 }
655         }
656
657         private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
658                 String uniqueId = null;
659
660                 if (resourceId != null) {
661                         uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
662                         artifactInfo.setUniqueId(uniqueId);
663                 }
664                 artifactInfo.setUserIdCreator(user.getUserId());
665                 String fullName = user.getFullName();
666                 artifactInfo.setUpdaterFullName(fullName);
667
668                 long time = System.currentTimeMillis();
669
670                 artifactInfo.setCreatorFullName(fullName);
671                 artifactInfo.setCreationDate(time);
672
673                 artifactInfo.setLastUpdateDate(time);
674                 artifactInfo.setUserIdLastUpdater(user.getUserId());
675
676                 artifactInfo.setMandatory(true);
677         }
678
679         /**
680          * 
681          * @param originNodeType
682          * @param componentInstance
683          * @param updatedContainerVertex
684          * @return
685          */
686         private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
687
688                 Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
689                 MapListCapabiltyDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
690                 StorageOperationStatus calculatedResult;
691                 if (allCalculatedCap != null) {
692                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
693
694                         if (calculatedResult != StorageOperationStatus.OK) {
695                                 return calculatedResult;
696                         }
697                 }
698                 Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
699                 if (capabiltiesProperties != null) {
700                         Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), e -> e.getValue()));
701                         MapCapabiltyProperty mapCapabiltyProperty = new MapCapabiltyProperty(updateKeyMap);
702                         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabiltyProperty, componentInstance.getUniqueId());
703                         if (calculatedResult != StorageOperationStatus.OK) {
704                                 return calculatedResult;
705                         }
706                 }
707
708                 MapListCapabiltyDataDefinition fullCalculatedCap = new MapListCapabiltyDataDefinition();
709                 calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
710
711                 if (calculatedResult != StorageOperationStatus.OK) {
712                         return calculatedResult;
713                 }
714
715                 Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
716
717                 MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
718
719                 StorageOperationStatus status;
720                 if (allCalculatedReq != null) {
721                         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
722                         if (status != StorageOperationStatus.OK) {
723                                 return status;
724                         }
725                 }
726                 MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
727                 status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
728                 return StorageOperationStatus.OK;
729
730         }
731
732         public static String createCapPropertyKey(String key, String instanceId) {
733                 StringBuffer sb = new StringBuffer(instanceId);
734                 sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
735                 return sb.toString();
736         }
737
738         public MapListCapabiltyDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
739                 if (capabilities != null) {
740                         MapListCapabiltyDataDefinition allCalculatedCap = new MapListCapabiltyDataDefinition();
741
742                         capabilities.entrySet().forEach(e -> {
743                                 List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition();
744                                 listCapabilities.forEach(cap -> {
745                                         cap.setSource(componentInstance.getComponentUid());
746                                         cap.addToPath(componentInstance.getUniqueId());
747                                         cap.setOwnerId(componentInstance.getUniqueId());
748                                         cap.setOwnerName(componentInstance.getName());
749                                         cap.setLeftOccurrences(cap.getMaxOccurrences());
750                                         allCalculatedCap.add(e.getKey(), cap);
751                                 });
752                         });
753                         return allCalculatedCap;
754                 }
755                 return null;
756         }
757
758         public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
759                 if (requirements != null) {
760                         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
761
762                         requirements.entrySet().forEach(e -> {
763                                 List<RequirementDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition();
764                                 listCapabilities.forEach(req -> {
765                                         req.setSource(componentInstance.getComponentUid());
766                                         req.addToPath(componentInstance.getUniqueId());
767                                         req.setOwnerId(componentInstance.getUniqueId());
768                                         req.setOwnerName(componentInstance.getName());
769                                         req.setLeftOccurrences(req.getMaxOccurrences());
770                                         allCalculatedReq.add(e.getKey(), req);
771                                 });
772                         });
773                         return allCalculatedReq;
774                 }
775                 return null;
776         }
777
778         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
779
780                 StorageOperationStatus result = null;
781                 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
782                 if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
783                         for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
784                                 Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
785                                 if (groupOptional.isPresent()) {
786                                         GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(groupOptional.get(), componentInstance);
787                                         groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(a -> a.getUniqueId()).collect(Collectors.toList()));
788                                         groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(a -> a.getArtifactUUID()).collect(Collectors.toList()));
789                                         groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
790                                 }
791                         }
792                 }
793                 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
794                         result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
795                 }
796                 if (result == null) {
797                         result = StorageOperationStatus.OK;
798                 }
799                 return result;
800         }
801
802         private GroupInstanceDataDefinition buildGroupInstanceDataDefinition(GroupDefinition group, ComponentInstance componentInstance) {
803
804                 String componentInstanceName = componentInstance.getName();
805                 Long creationDate = System.currentTimeMillis();
806                 GroupInstanceDataDefinition groupInstance = new GroupInstanceDataDefinition();
807                 String groupUid = group.getUniqueId();
808
809                 groupInstance.setGroupUid(groupUid);
810                 groupInstance.setType(group.getType());
811                 groupInstance.setCustomizationUUID(generateCustomizationUUID());
812                 groupInstance.setCreationTime(creationDate);
813                 groupInstance.setModificationTime(creationDate);
814                 groupInstance.setName(buildGroupInstanceName(componentInstanceName, group.getName()));
815                 groupInstance.setGroupName(groupInstance.getName());
816                 groupInstance.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(groupInstance.getName()));
817                 groupInstance.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(componentInstance.getUniqueId(), groupUid, groupInstance.getNormalizedName()));
818                 groupInstance.setArtifacts(group.getArtifacts());
819                 groupInstance.setArtifactsUuid(group.getArtifactsUuid());
820                 groupInstance.setProperties(group.getProperties());
821                 groupInstance.setInvariantUUID(group.getInvariantUUID());
822                 groupInstance.setGroupUUID(group.getGroupUUID());
823                 groupInstance.setVersion(group.getVersion());
824
825                 return groupInstance;
826         }
827
828         private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
829                 String ciOriginComponentUid = resourceInstance.getComponentUid();
830
831                 if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
832                         resourceInstance.setCustomizationUUID(generateCustomizationUUID());
833                 }
834                 ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
835
836                 Long creationDate = resourceInstance.getCreationTime();
837                 if (creationDate == null) {
838                         creationDate = System.currentTimeMillis();
839                 }
840                 dataDefinition.setComponentUid(ciOriginComponentUid);
841                 dataDefinition.setCreationTime(creationDate);
842                 dataDefinition.setModificationTime(creationDate);
843                 if (StringUtils.isNotEmpty(instanceNewName)) {
844                         dataDefinition.setName(instanceNewName);
845                         resourceInstance.setName(instanceNewName);
846                 }
847                 if (StringUtils.isNotEmpty(dataDefinition.getName()))
848                         dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
849                 dataDefinition.setIcon(resourceInstance.getIcon());
850                 if (generateUid) {
851                         dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
852                         resourceInstance.setUniqueId(dataDefinition.getUniqueId());
853                 }
854                 if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
855                         dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
856                 if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
857                         dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
858                 if (StringUtils.isEmpty(dataDefinition.getToscaComponentName()) && originToscaElement != null)
859                         dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
860                 if (dataDefinition.getOriginType() == null && originToscaElement != null) {
861                         ResourceTypeEnum resourceType = originToscaElement.getResourceType();
862                         OriginTypeEnum originType = null;
863                         switch (resourceType) {
864                         case VF:
865                                 originType = OriginTypeEnum.VF;
866                                 break;
867                         case VFC:
868                                 originType = OriginTypeEnum.VFC;
869                                 break;
870                         case VL:
871                                 originType = OriginTypeEnum.VL;
872                                 break;
873                         case CP:
874                                 originType = OriginTypeEnum.CP;
875                                 break;
876                         default:
877                                 break;
878                         }
879                         dataDefinition.setOriginType(originType);
880                 }
881                 return dataDefinition;
882         }
883
884         private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
885                 Boolean isUniqueName = true;
886                 try {
887                         isUniqueName = !container.getComponentInstances().values().stream().filter(ci -> ci.getName() != null && ci.getName().equals(instanceName)).findAny().isPresent();
888
889                 } catch (Exception e) {
890                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
891                 }
892                 return isUniqueName;
893         }
894
895         private String buildGroupInstanceName(String instanceName, String groupName) {
896                 int groupNameIndex = groupName.indexOf("..");
897                 //turn group name from VFName..heatfile..module-n to VFiName..heatfile..module-n
898                 return ValidationUtils.normaliseComponentName(instanceName) + groupName.substring(groupNameIndex);
899         }
900
901         private String generateCustomizationUUID() {
902                 return UUID.randomUUID().toString();
903         }
904
905         private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
906                 return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
907         }
908
909         public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, RequirementCapabilityRelDef relation) {
910                 List<RequirementCapabilityRelDef> relations = new ArrayList<>();
911                 relations.add(relation);
912                 Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(componentId, relations);
913                 if (associateResourceInstances.isRight()) {
914                         return Either.right(associateResourceInstances.right().value());
915                 }
916                 return Either.left(associateResourceInstances.left().value().get(0));
917         }
918
919         @SuppressWarnings({ "unchecked" })
920         public Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(String componentId, List<RequirementCapabilityRelDef> relations) {
921
922                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
923                 if (containerVEither.isRight()) {
924                         TitanOperationStatus error = containerVEither.right().value();
925                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
926                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
927                 }
928                 GraphVertex containerV = containerVEither.left().value();
929                 List<RequirementAndRelationshipPair> relationshipsResult = new ArrayList<RequirementAndRelationshipPair>();
930                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
931                 if (capResult.isRight()) {
932                         return Either.right(capResult.right().value());
933
934                 }
935                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
936
937                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
938                 if (capResult.isRight()) {
939                         return Either.right(capResult.right().value());
940
941                 }
942                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
943
944                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
945                 if (reqResult.isRight()) {
946                         return Either.right(reqResult.right().value());
947                 }
948                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
949
950                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
951                 if (reqResult.isRight()) {
952                         return Either.right(reqResult.right().value());
953                 }
954                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
955
956                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
957                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
958
959                 StorageOperationStatus status;
960                 List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
961                 for (RequirementCapabilityRelDef relation : relations) {
962
963                         String fromNode = relation.getFromNode();
964                         String toNode = relation.getToNode();
965                         List<RequirementAndRelationshipPair> relationships = relation.getRelationships();
966                         if (relationships == null || relationships.isEmpty()) {
967                                 BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
968                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
969                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
970                         }
971
972                         for (RequirementAndRelationshipPair immutablePair : relationships) {
973                                 String requirement = immutablePair.getRequirement();
974
975                                 Either<RelationshipInstDataDefinition, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair, calculatedCapabilty, calculatedRequirement, fullFilledCapabilty, fullfilledRequirement,
976                                                 compositionDataDefinition, containerV.getUniqueId());
977
978                                 if (associateRes.isRight()) {
979                                         status = associateRes.right().value();
980                                         BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
981                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
982                                         return Either.right(status);
983                                 }
984
985                                 RelationshipInstDataDefinition relationshipInstData = associateRes.left().value();
986                                 RelationshipImpl relationshipImplResult = new RelationshipImpl();
987                                 relationshipImplResult.setType(relationshipInstData.getType());
988                                 RequirementAndRelationshipPair requirementAndRelationshipPair = new RequirementAndRelationshipPair(requirement, relationshipImplResult);
989                                 requirementAndRelationshipPair.setCapability(immutablePair.getCapability());
990                                 requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
991                                 requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
992                                 requirementAndRelationshipPair.setCapabilityUid(immutablePair.getCapabilityUid());
993                                 requirementAndRelationshipPair.setRequirementUid(immutablePair.getRequirementUid());
994                                 relationshipsResult.add(requirementAndRelationshipPair);
995                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
996                                 status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
997                                 if (status != StorageOperationStatus.OK) {
998                                         return Either.right(status);
999                                 }
1000                                 status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
1001                                 if (status != StorageOperationStatus.OK) {
1002                                         return Either.right(status);
1003                                 }
1004                         }
1005                         RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef();
1006                         capabilityRelDef.setFromNode(fromNode);
1007                         capabilityRelDef.setToNode(toNode);
1008                         capabilityRelDef.setRelationships(relationshipsResult);
1009                         relationsList.add(capabilityRelDef);
1010                 }
1011                 // update metadata of container and composition json
1012                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1013                 if (status != StorageOperationStatus.OK) {
1014                         return Either.right(status);
1015                 }
1016
1017                 return Either.left(relationsList);
1018         }
1019
1020         private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult,
1021                         Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
1022                         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
1023                 containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1024                 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(containerV);
1025                 if (updateElement.isRight()) {
1026                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
1027                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1028                 }
1029                 // update cap/req jsons, fullfilled cap/req jsons!!!!!
1030                 Either<GraphVertex, TitanOperationStatus> status;
1031                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
1032                 status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1033                 if (status.isRight()) {
1034                         TitanOperationStatus error = status.right().value();
1035                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
1036                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1037                 }
1038
1039                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1040                 status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1041                 if (status.isRight()) {
1042                         TitanOperationStatus error = status.right().value();
1043                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
1044                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1045                 }
1046
1047                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
1048                 status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1049                 if (status.isRight()) {
1050                         TitanOperationStatus error = status.right().value();
1051                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
1052                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1053                 }
1054
1055                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
1056                 status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1057                 if (status.isRight()) {
1058                         TitanOperationStatus error = status.right().value();
1059                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
1060                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
1061                 }
1062                 return StorageOperationStatus.OK;
1063         }
1064
1065         @SuppressWarnings({ "unchecked" })
1066         public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
1067                 if (requirementDef.getRelationships() == null) {
1068                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
1069                         return Either.right(StorageOperationStatus.BAD_REQUEST);
1070                 }
1071
1072                 String fromResInstanceUid = requirementDef.getFromNode();
1073                 String toResInstanceUid = requirementDef.getToNode();
1074
1075                 Either<GraphVertex, TitanOperationStatus> containerVEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1076                 if (containerVEither.isRight()) {
1077                         TitanOperationStatus error = containerVEither.right().value();
1078                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch container vertex {} error {}", componentId, error);
1079                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1080                 }
1081                 GraphVertex containerV = containerVEither.left().value();
1082
1083                 // DE191707 - validatations
1084                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1085                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1086                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1087                 ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
1088                 if (ciFrom == null) {
1089                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
1090                         return Either.right(StorageOperationStatus.NOT_FOUND);
1091
1092                 }
1093                 ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
1094                 if (ciFrom == ciTo) {
1095                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
1096                         return Either.right(StorageOperationStatus.NOT_FOUND);
1097
1098                 }
1099                 Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
1100
1101                 List<RequirementAndRelationshipPair> relationPairList = requirementDef.getRelationships();
1102                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1103                 if (capResult.isRight()) {
1104                         return Either.right(capResult.right().value());
1105
1106                 }
1107                 Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
1108
1109                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1110                 if (capResult.isRight()) {
1111                         return Either.right(capResult.right().value());
1112
1113                 }
1114                 Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
1115
1116                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1117                 if (reqResult.isRight()) {
1118                         return Either.right(reqResult.right().value());
1119                 }
1120                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1121
1122                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1123                 if (reqResult.isRight()) {
1124                         return Either.right(reqResult.right().value());
1125                 }
1126                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
1127
1128                 for (RequirementAndRelationshipPair relationPair : relationPairList) {
1129                         Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
1130                         boolean isDeleted = false;
1131                         while (iterator.hasNext()) {
1132                                 Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
1133                                 RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
1134                                 if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid)) {
1135                                         if (relationPair.equalsTo(relationInJson)) {
1136                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Remove relation from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(),
1137                                                                 relationInJson.getCapabilityOwnerId(), relationInJson.getRequirementOwnerId());
1138                                                 iterator.remove();
1139
1140                                                 // update calculated cap/req
1141                                                 StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, toResInstanceUid, relationInJson);
1142                                                 if (status != StorageOperationStatus.OK) {
1143                                                         return Either.right(status);
1144                                                 }
1145                                                 status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, fromResInstanceUid, relationInJson);
1146                                                 if (status != StorageOperationStatus.OK) {
1147                                                         return Either.right(status);
1148                                                 }
1149                                                 isDeleted = true;
1150                                         }
1151                                 }
1152                         }
1153                         if (isDeleted == false) {
1154                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
1155                                                 relationPair.getCapabilityOwnerId(), relationPair.getRequirementOwnerId());
1156                                 return Either.right(StorageOperationStatus.NOT_FOUND);
1157                         }
1158                 }
1159                 StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
1160                 if (status != StorageOperationStatus.OK) {
1161                         return Either.right(status);
1162                 }
1163                 status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
1164                 if (status != StorageOperationStatus.OK) {
1165                         return Either.right(status);
1166                 }
1167
1168                 // update jsons
1169                 // update metadata of container and composition json
1170                 status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1171                 if (status != StorageOperationStatus.OK) {
1172                         return Either.right(status);
1173                 }
1174
1175                 return Either.left(requirementDef);
1176         }
1177
1178         private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1179                         RelationshipInstDataDefinition relation) {
1180                 StorageOperationStatus status;
1181                 MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
1182                 if (reqByInstance == null) {
1183                         // move from fullfilled
1184                         status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation);
1185                 } else {
1186                         ListRequirementDataDefinition reqByType = reqByInstance.findByKey(relation.getType());
1187                         if (reqByType == null) {
1188                                 // move from fullfilled
1189                                 status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation);
1190                         } else {
1191                                 Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
1192                                                 .filter(cap -> cap.getOwnerId().equals(relation.getRequirementOwnerId()) && cap.getName().equals(relation.getRequirement()) && cap.getUniqueId().equals(relation.getRequirementId())).findFirst();
1193
1194                                 if (requirementOptional.isPresent()) {
1195
1196                                         RequirementDataDefinition requirement = requirementOptional.get();
1197                                         String leftOccurrences = requirement.getLeftOccurrences();
1198                                         if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1199                                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1200                                                 ++leftIntValue;
1201                                                 requirement.setLeftOccurrences(String.valueOf(leftIntValue));
1202                                         }
1203                                         status = StorageOperationStatus.OK;
1204                                 } else {
1205                                         // move from fullfilled
1206                                         status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation);
1207                                 }
1208                         }
1209                 }
1210                 return status;
1211         }
1212
1213         private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty, String toResInstanceUid,
1214                         RelationshipInstDataDefinition relation) {
1215                 StorageOperationStatus status;
1216                 MapListCapabiltyDataDefinition capByInstance = calculatedCapabilty.get(toResInstanceUid);
1217                 if (capByInstance == null) {
1218                         // move from fullfilled
1219                         status = moveFromFullFilledCapabilty(calculatedCapabilty, fullFilledCapabilty, toResInstanceUid, relation);
1220                 } else {
1221                         ListCapabilityDataDefinition capByType = capByInstance.findByKey(relation.getType());
1222                         if (capByType == null) {
1223                                 // move from fullfilled
1224                                 status = moveFromFullFilledCapabilty(calculatedCapabilty, fullFilledCapabilty, toResInstanceUid, relation);
1225                         } else {
1226                                 Optional<CapabilityDataDefinition> capabiltyOptional = capByType.getListToscaDataDefinition().stream()
1227                                                 .filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabiltyId())).findFirst();
1228
1229                                 if (capabiltyOptional.isPresent()) {
1230
1231                                         CapabilityDataDefinition capability = capabiltyOptional.get();
1232                                         String leftOccurrences = capability.getLeftOccurrences();
1233                                         if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1234                                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1235                                                 ++leftIntValue;
1236                                                 capability.setLeftOccurrences(String.valueOf(leftIntValue));
1237                                         }
1238                                         status = StorageOperationStatus.OK;
1239                                 } else {
1240                                         // move from fullfilled
1241                                         status = moveFromFullFilledCapabilty(calculatedCapabilty, fullFilledCapabilty, toResInstanceUid, relation);
1242                                 }
1243                         }
1244                 }
1245                 return status;
1246         }
1247
1248         private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListCapabiltyDataDefinition> fullFilledCapabilty, String toResInstanceUid,
1249                         RelationshipInstDataDefinition relation) {
1250                 MapListCapabiltyDataDefinition capByInstance = fullFilledCapabilty.get(toResInstanceUid);
1251                 if (capByInstance == null) {
1252                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capabilty in fullfilled list for instance {} ", toResInstanceUid);
1253                         return StorageOperationStatus.GENERAL_ERROR;
1254                 }
1255                 ListCapabilityDataDefinition capByType = capByInstance.findByKey(relation.getType());
1256                 if (capByType == null) {
1257                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capabilty type {} in fullfilled list for instance {} ", relation.getType(), toResInstanceUid);
1258                         return StorageOperationStatus.GENERAL_ERROR;
1259                 }
1260                 Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
1261                 boolean found = false;
1262                 while (iterator.hasNext()) {
1263                         CapabilityDataDefinition cap = iterator.next();
1264                         if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getName().equals(relation.getRequirement()) && cap.getUniqueId().equals(relation.getCapabiltyId())) {
1265                                 found = true;
1266                                 iterator.remove();
1267                                 // return to calculated list
1268                                 String leftOccurrences = cap.getLeftOccurrences();
1269                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1270                                 ++leftIntValue;
1271                                 cap.setLeftOccurrences(String.valueOf(leftIntValue));
1272
1273                                 MapListCapabiltyDataDefinition mapListCapaDataDef = calculatedCapabilty.get(toResInstanceUid);
1274                                 if (mapListCapaDataDef == null) {
1275                                         mapListCapaDataDef = new MapListCapabiltyDataDefinition();
1276                                 }
1277                                 ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(relation.getType());
1278                                 if (findByKey == null) {
1279                                         findByKey = new ListCapabilityDataDefinition();
1280                                         mapListCapaDataDef.put(relation.getType(), findByKey);
1281                                 }
1282                                 findByKey.add(cap);
1283                                 break;
1284                         }
1285                 }
1286                 if (found == false) {
1287                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No capabilty type {} with ownerId {} in fullfilled list for instance {} ", relation.getType(), relation.getCapabilityOwnerId(), toResInstanceUid);
1288                         return StorageOperationStatus.GENERAL_ERROR;
1289                 }
1290                 return StorageOperationStatus.OK;
1291         }
1292
1293         private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1294                         RelationshipInstDataDefinition relation) {
1295                 MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
1296                 if (reqByInstance == null) {
1297                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
1298                         return StorageOperationStatus.GENERAL_ERROR;
1299                 }
1300                 ListRequirementDataDefinition reqByType = reqByInstance.findByKey(relation.getType());
1301                 if (reqByType == null) {
1302                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement type {} in fullfilled list for instance {} ", relation.getType(), fromResInstanceUid);
1303                         return StorageOperationStatus.GENERAL_ERROR;
1304                 }
1305                 Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
1306                 boolean found = false;
1307                 while (iterator.hasNext()) {
1308                         RequirementDataDefinition req = iterator.next();
1309                         if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
1310                                 found = true;
1311                                 iterator.remove();
1312                                 // return to calculated list
1313                                 String leftOccurrences = req.getLeftOccurrences();
1314                                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1315                                 ++leftIntValue;
1316                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1317
1318                                 MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
1319                                 if (mapListReqDataDef == null) {
1320                                         mapListReqDataDef = new MapListRequirementDataDefinition();
1321                                 }
1322                                 ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(relation.getType());
1323                                 if (findByKey == null) {
1324                                         findByKey = new ListRequirementDataDefinition();
1325                                         mapListReqDataDef.put(relation.getType(), findByKey);
1326                                 }
1327                                 findByKey.add(req);
1328                                 break;
1329                         }
1330                 }
1331                 if (found == false) {
1332                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fullfilled list for instance {} ", relation.getType(), relation.getCapabilityOwnerId(), fromResInstanceUid);
1333                         return StorageOperationStatus.GENERAL_ERROR;
1334                 }
1335                 return StorageOperationStatus.OK;
1336
1337         }
1338
1339         public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
1340                 ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
1341
1342                 if (componentInstance == null) {
1343                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
1344                         return StorageOperationStatus.NOT_FOUND;
1345                 }
1346                 UUID uuid = UUID.randomUUID();
1347                 componentInstance.setCustomizationUUID(uuid.toString());
1348
1349                 return StorageOperationStatus.OK;
1350         }
1351
1352         public Either<RelationshipInstDataDefinition, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RequirementAndRelationshipPair relationPair,
1353                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1354                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
1355                 String requirement = relationPair.getRequirement();
1356                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1357
1358                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
1359
1360                 ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
1361                 if (fromResourceInstData == null) {
1362                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
1363                         return Either.right(StorageOperationStatus.NOT_FOUND);
1364                 }
1365                 ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
1366                 if (toResourceInstData == null) {
1367                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
1368                         return Either.right(StorageOperationStatus.NOT_FOUND);
1369                 }
1370
1371                 Either<RelationshipInstDataDefinition, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
1372                                 fullfilledRequirement, containerId);
1373                 if (reqVsCap.isRight()) {
1374                         StorageOperationStatus status = reqVsCap.right().value();
1375                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
1376                         return Either.right(status);
1377                 }
1378                 RelationshipInstDataDefinition relation = reqVsCap.left().value();
1379
1380                 // add to json new relations
1381                 compositionDataDefinition.addRelation(relation.getUniqueId(), relation);
1382
1383                 return Either.left(relation);
1384         }
1385
1386         private Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
1387
1388                 Either<Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>>, TitanOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
1389                 if (calculatedCapabiltyEither.isRight()) {
1390                         TitanOperationStatus error = calculatedCapabiltyEither.right().value();
1391                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
1392                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1393                 }
1394                 Pair<GraphVertex, Map<String, MapListCapabiltyDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
1395                 return Either.left(calculatedCapabilty);
1396         }
1397
1398         private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
1399                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, TitanOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
1400                 if (calculatedRequirementEither.isRight()) {
1401                         TitanOperationStatus error = calculatedRequirementEither.right().value();
1402                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
1403                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1404                 }
1405                 Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
1406                 return Either.left(calculatedRequirement);
1407         }
1408
1409         private Either<RelationshipInstDataDefinition, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance, RequirementAndRelationshipPair relationPair,
1410                         Map<String, MapListCapabiltyDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabiltyDataDefinition> fullfilledCapabilty,
1411                         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
1412                 String type = relationPair.getRelationship().getType();
1413                 // capability
1414
1415                 String toInstId = toResInstance.getUniqueId();
1416                 MapListCapabiltyDataDefinition mapListCapabiltyDataDefinition = calculatedCapabilty.get(toInstId);
1417
1418                 if (mapListCapabiltyDataDefinition == null) {
1419                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
1420                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1421                 }
1422                 ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabiltyDataDefinition.getMapToscaDataDefinition().get(type);
1423                 if (listCapabilityDataDefinition == null) {
1424                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
1425                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1426                 }
1427                 CapabilityDataDefinition capabiltyForRelation = null;
1428                 Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
1429                 while (iteratorCap.hasNext()) {
1430                         CapabilityDataDefinition cap = iteratorCap.next();
1431                         if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
1432                                 capabiltyForRelation = cap;
1433                                 String leftOccurrences = cap.getLeftOccurrences();
1434                                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1435                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1436                                         if (leftIntValue > 0) {
1437                                                 --leftIntValue;
1438                                                 capabiltyForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
1439                                                 if (leftIntValue == 0) {
1440                                                         // remove from calculated
1441                                                         iteratorCap.remove();
1442                                                         // move to fullfilled
1443                                                         MapListCapabiltyDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
1444                                                         if (mapListCapabiltyFullFilledInst == null) {
1445                                                                 mapListCapabiltyFullFilledInst = new MapListCapabiltyDataDefinition();
1446                                                                 fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
1447                                                         }
1448
1449                                                         ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
1450                                                         if (listCapabilityFull == null) {
1451                                                                 listCapabilityFull = new ListCapabilityDataDefinition();
1452                                                                 mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
1453                                                         }
1454                                                         listCapabilityFull.add(capabiltyForRelation);
1455                                                 }
1456                                                 break;
1457                                         } else {
1458                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabiltyForRelation.getType(), toInstId, containerId);
1459                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1460                                         }
1461                                 }
1462                         }
1463                 }
1464                 if (capabiltyForRelation == null) {
1465                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
1466                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1467                 }
1468
1469                 // requirements
1470                 String fromInstId = fromResInstance.getUniqueId();
1471                 MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
1472                 if (mapListRequirementDataDefinition == null) {
1473                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
1474                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1475                 }
1476                 ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
1477                 if (listRequirementDataDefinition == null) {
1478                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
1479                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1480                 }
1481
1482                 RequirementDataDefinition requirementForRelation = null;
1483                 Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
1484                 while (iteratorReq.hasNext()) {
1485                         RequirementDataDefinition req = iteratorReq.next();
1486                         if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
1487                                 requirementForRelation = req;
1488
1489                                 String leftOccurrences = req.getLeftOccurrences();
1490                                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1491                                         Integer leftIntValue = Integer.parseInt(leftOccurrences);
1492                                         if (leftIntValue > 0) {
1493                                                 --leftIntValue;
1494                                                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1495                                                 if (leftIntValue == 0) {
1496                                                         // remove from calculated
1497                                                         iteratorReq.remove();
1498                                                         // move to fullfilled
1499                                                         MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
1500                                                         if (mapListRequirementFullFilledInst == null) {
1501                                                                 mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
1502                                                                 fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
1503                                                         }
1504
1505                                                         ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
1506                                                         if (listRequirementFull == null) {
1507                                                                 listRequirementFull = new ListRequirementDataDefinition();
1508                                                                 mapListRequirementFullFilledInst.put(type, listRequirementFull);
1509                                                         }
1510                                                         listRequirementFull.add(requirementForRelation);
1511                                                 }
1512                                                 break;
1513                                         } else {
1514                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
1515                                                 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1516                                         }
1517                                 }
1518                         }
1519                 }
1520                 if (!capabiltyForRelation.getType().equals(requirementForRelation.getCapability())) {
1521                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "No math for capabilty from type {} and requirement {} from {} to {} in container {}.", capabiltyForRelation.getType(), requirementForRelation.getCapability(), fromInstId, toInstId,
1522                                         containerId);
1523                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1524                 }
1525
1526                 RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair);
1527
1528                 relationshipTypeData.setType(type);
1529
1530                 return Either.left(relationshipTypeData);
1531         }
1532
1533         private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RequirementAndRelationshipPair relationPair) {
1534
1535                 RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
1536                 relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
1537
1538                 relationshipInstData.setType(relationPair.getRelationship().getType());
1539                 Long creationDate = System.currentTimeMillis();
1540                 relationshipInstData.setCreationTime(creationDate);
1541                 relationshipInstData.setModificationTime(creationDate);
1542                 relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
1543                 relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
1544                 relationshipInstData.setCapabiltyId(relationPair.getCapabilityUid());
1545                 relationshipInstData.setRequirementId(relationPair.getRequirementUid());
1546                 relationshipInstData.setFromId(fromResInstanceUid);
1547                 relationshipInstData.setToId(toInstId);
1548                 relationshipInstData.setRequirement(relationPair.getRequirement());
1549                 relationshipInstData.setCapability(relationPair.getCapability());
1550
1551                 return relationshipInstData;
1552         }
1553
1554         public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
1555
1556                 StorageOperationStatus result = null;
1557                 String containerId = containerComponent.getUniqueId();
1558                 Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
1559                 Either<GraphVertex, TitanOperationStatus> updateElement = null;
1560                 if (!validateInstanceNames(resourcesInstancesMap)) {
1561                         result = StorageOperationStatus.INCONSISTENCY;
1562                 }
1563                 if (result == null) {
1564                         if (!validateInstanceNames(resourcesInstancesMap)) {
1565                                 result = StorageOperationStatus.INCONSISTENCY;
1566                         }
1567                 }
1568                 if (result == null && !allowDeleted) {
1569                         if (!validateDeletedResources(resourcesInstancesMap)) {
1570                                 result = StorageOperationStatus.INCONSISTENCY;
1571                         }
1572                 }
1573                 if (result == null) {
1574                         instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
1575                 }
1576                 if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
1577                         containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1578                         Map<String, CompositionDataDefinition> compositions = new HashMap<>();
1579                         CompositionDataDefinition composition = new CompositionDataDefinition();
1580                         composition.setComponentInstances(instancesJsonData);
1581                         compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
1582                         containerVertex.setJson(compositions);
1583                         updateElement = titanDao.updateVertex(containerVertex);
1584                         if (updateElement.isRight()) {
1585                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
1586                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value());
1587                         }
1588                 }
1589                 if (result == null) {
1590                         result = StorageOperationStatus.OK;
1591                 }
1592                 return result;
1593         }
1594
1595         private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
1596
1597                 Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
1598                 for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
1599                         ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
1600                         instances.put(instance.getUniqueId(), instance);
1601                 }
1602                 return instances;
1603         }
1604
1605         private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1606                 boolean result = true;
1607                 for (Resource resource : resourcesInstancesMap.values()) {
1608                         if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
1609                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
1610                                 result = false;
1611                                 break;
1612                         }
1613                 }
1614                 return result;
1615         }
1616
1617         private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
1618                 boolean result = true;
1619                 Set<String> names = new HashSet<>();
1620                 for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
1621                         if (StringUtils.isEmpty(instance.getName())) {
1622                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
1623                                 result = false;
1624                                 break;
1625                         } else if (names.contains(instance.getName())) {
1626                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ", instance.getName());
1627                                 result = false;
1628                                 break;
1629                         } else {
1630                                 names.add(instance.getName());
1631                         }
1632                 }
1633                 return result;
1634         }
1635
1636         public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
1637                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
1638                 if (metadataVertex.isRight()) {
1639                         TitanOperationStatus status = metadataVertex.right().value();
1640                         if (status == TitanOperationStatus.NOT_FOUND) {
1641                                 status = TitanOperationStatus.INVALID_ID;
1642                         }
1643                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1644                 }
1645                 MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
1646                 return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArtifacts, instanceId);
1647
1648         }
1649
1650         @SuppressWarnings({ "unchecked" })
1651         public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
1652                 Either<GraphVertex, TitanOperationStatus> metadataVertex = titanDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1653                 if (metadataVertex.isRight()) {
1654                         TitanOperationStatus status = metadataVertex.right().value();
1655                         if (status == TitanOperationStatus.NOT_FOUND) {
1656                                 status = TitanOperationStatus.INVALID_ID;
1657                         }
1658                         return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1659                 }
1660                 GraphVertex metaVertex = metadataVertex.left().value();
1661                 Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
1662                 CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1663                 StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
1664                 if (status != StorageOperationStatus.OK) {
1665                         logger.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
1666                         return status;
1667                 }
1668                 Either<GraphVertex, TitanOperationStatus> updateVertex = titanDao.updateVertex(metaVertex);
1669                 if (updateVertex.isRight()) {
1670                         logger.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
1671                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertex.right().value());
1672                 }
1673                 return StorageOperationStatus.OK;
1674         }
1675
1676         public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
1677                 if (groupInstances != null) {
1678                         Either<Map<String, MapGroupsDataDefinition>, TitanOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
1679                         if (dataFromGraph.isRight()) {
1680                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
1681                         }
1682                         MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
1683                         if (grInstPerInstance == null) {
1684                                 logger.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
1685                                 return StorageOperationStatus.NOT_FOUND;
1686                         }
1687                         for (String instGroupForUpdate : groupInstances) {
1688                                 GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
1689                                 if (groupInst == null) {
1690                                         logger.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
1691                                         continue;
1692                                 }
1693                                 UUID uuid = UUID.randomUUID();
1694                                 groupInst.setCustomizationUUID(uuid.toString());
1695                         }
1696
1697                 }
1698                 return StorageOperationStatus.OK;
1699         }
1700
1701         public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
1702
1703                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
1704                                 new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(gi -> gi.getName(), gi -> gi))), componentInstance.getUniqueId());
1705         }
1706
1707         public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
1708
1709                 return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
1710                                 componentInstance.getUniqueId());
1711         }
1712
1713         public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1714
1715                 List<String> pathKeys = new ArrayList<>();
1716                 pathKeys.add(componentInstanceId);
1717                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1718         }
1719
1720         public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
1721                 List<String> pathKeys = new ArrayList<>();
1722                 pathKeys.add(componentInstanceId);
1723                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
1724         }
1725
1726         public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
1727
1728                 List<String> pathKeys = new ArrayList<>();
1729                 pathKeys.add(componentInstanceId);
1730                 return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
1731         }
1732
1733         public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
1734                 List<String> pathKeys = new ArrayList<>();
1735                 pathKeys.add(componentInstanceId);
1736                 return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
1737         }
1738
1739
1740 }