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