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