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