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