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