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