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