Support for Test Topology Auto Design- Service Import
[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                 log.debug("enter populateCapability,get Capability OwnerId:{},get componentInstance UniqueId:{}",
780                         cap.getOwnerId(), componentInstance.getUniqueId());
781                 cap.setOwnerId(componentInstance.getUniqueId());
782                 log.debug("enter populateCapability,get Capability OwnerName:{},get componentInstance Name:{}",
783                         cap.getOwnerName(), componentInstance.getName());
784                 if (cap.getOwnerName() == null || cap.getOwnerName().isEmpty()) {
785                     cap.setOwnerName(componentInstance.getName());
786                 }
787                 cap.setLeftOccurrences(cap.getMaxOccurrences());
788                 allCalculatedCap.add(key, cap);
789             });
790         });
791     }
792
793     private MapListRequirementDataDefinition prepareCalculatedRequirementForTopologyTemplate(
794             Map<String, ListRequirementDataDefinition> requirements,
795             ComponentInstanceDataDefinition componentInstance,
796             MapListRequirementDataDefinition calculatedReqs) {
797             MapListRequirementDataDefinition allCalculatedReq =
798                     new MapListRequirementDataDefinition(calculatedReqs);
799
800             populateRequirement(requirements, componentInstance, allCalculatedReq);
801             return allCalculatedReq;
802     }
803     private void populateRequirement(Map<String, ListRequirementDataDefinition> requirements,
804                                      ComponentInstanceDataDefinition componentInstance,
805                                      MapListRequirementDataDefinition allCalculatedReq) {
806         requirements.forEach((key, value) -> {
807             List<RequirementDataDefinition> listRequirements = value.getListToscaDataDefinition()
808                     .stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
809             listRequirements.forEach(req -> {
810                 req.setSource(componentInstance.getComponentUid());
811                 req.addToPath(componentInstance.getUniqueId());
812                 log.debug("enter populateRequirement,get init Requirements OwnerId:{},get componentInstance UniqueId:{}",
813                         req.getOwnerId(), componentInstance.getUniqueId());
814                 if (req.getOwnerId() == null || req.getOwnerId().isEmpty()) {
815                     req.setOwnerId(componentInstance.getUniqueId());
816                 }
817                 log.debug("enter populateRequirement,get init Requirements OwnerName:{}", req.getOwnerName());
818                 if (req.getOwnerName() == null || req.getOwnerName().isEmpty()) {
819                     req.setOwnerName(componentInstance.getName());
820                 }
821                 req.setLeftOccurrences(req.getMaxOccurrences());
822                 allCalculatedReq.add(key, req);
823             });
824         });
825     }
826
827
828
829     private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
830         Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
831
832         MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
833         if (calculatedCapabilities != null) {
834             calculatedCapabilities.forEach((key1, value1) -> {
835                 Map<String, ListCapabilityDataDefinition> mapByType = value1.getMapToscaDataDefinition();
836                 mapByType.forEach((key, value) -> value.getListToscaDataDefinition().forEach(cap -> {
837                     cap.addToPath(componentInstance.getUniqueId());
838                     allCalculatedCap.add(key, cap);
839                 }));
840             });
841         }
842         MapListCapabilityDataDefinition allCaps;
843         Map<String, ListCapabilityDataDefinition> capabilities = originTopologyTemplate.getCapabilities();
844         if (MapUtils.isNotEmpty(capabilities)) {
845             allCaps = prepareCalculatedCapabiltyForTopologyTemplate(capabilities, componentInstance,
846                     allCalculatedCap);
847         } else {
848             allCaps = new MapListCapabilityDataDefinition(allCalculatedCap);
849         }
850         if(!allCaps.isEmpty()) {
851             StorageOperationStatus calculatedCapabilitiesResult =
852                     addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
853                             EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES,
854                             allCaps, componentInstance.getUniqueId());
855             if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
856                 return calculatedCapabilitiesResult;
857             }
858             MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
859             calculatedCapabilitiesResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
860                     EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES,
861                     fullCalculatedCap, componentInstance.getUniqueId());
862             if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
863                 return calculatedCapabilitiesResult;
864             }
865         }
866         Map<String, MapListRequirementDataDefinition> calculatedRequirements =
867                 originTopologyTemplate.getCalculatedRequirements();
868         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
869         if (calculatedRequirements != null) {
870             calculatedRequirements.forEach((key, value) -> {
871                 Map<String, ListRequirementDataDefinition> mapByType =
872                         value.getMapToscaDataDefinition();
873                 mapByType.forEach((key1, value1) -> value1.getListToscaDataDefinition().stream()
874                         .filter(RequirementDataDefinition::isExternal).forEach(req -> {
875                     req.addToPath(componentInstance.getUniqueId());
876                     req.setExternal(false);
877                     allCalculatedReq.add(key1, req);
878                 }));
879             });
880
881         }
882
883         MapListRequirementDataDefinition allReqs;
884         Map<String, ListRequirementDataDefinition> requirements = originTopologyTemplate.getRequirements();
885         if (MapUtils.isNotEmpty(requirements)) {
886             allReqs = prepareCalculatedRequirementForTopologyTemplate(requirements,
887                     componentInstance, allCalculatedReq);
888         } else
889             allReqs = new MapListRequirementDataDefinition(allCalculatedReq);
890
891         if(!allReqs.isEmpty()) {
892             StorageOperationStatus calculatedRequirementResult =
893                     addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
894                             EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS,
895                             allReqs, componentInstance.getUniqueId());
896             if (calculatedRequirementResult != StorageOperationStatus.OK) {
897                 return calculatedRequirementResult;
898             }
899             MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
900             calculatedRequirementResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
901                     EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS,
902                     fullCalculatedReq,
903                     componentInstance.getUniqueId());
904             if (calculatedRequirementResult != StorageOperationStatus.OK) {
905                 return calculatedRequirementResult;
906             }
907         }
908         Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
909         Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
910
911         if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
912             for (MapCapabilityProperty map : calculatedCapabilitiesProperties.values()) {
913                 for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
914                     String newKey = (componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
915                     updateKeyMap.put(newKey, entry.getValue());
916                 }
917             }
918         }
919         Map<String, MapPropertiesDataDefinition> capabilitiesProperties =
920                 originTopologyTemplate.getCapabilitiesProperties();
921         Map<String, MapPropertiesDataDefinition> updateKeyMapCapabilitiesProperties;
922         if (MapUtils.isNotEmpty(capabilitiesProperties)) {
923             updateKeyMapCapabilitiesProperties = capabilitiesProperties.entrySet().stream()
924                     .collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(),
925                             componentInstance.getUniqueId()), Entry::getValue));
926         }
927         else {
928             updateKeyMapCapabilitiesProperties = new HashMap<>();
929         }
930         updateKeyMap.putAll(updateKeyMapCapabilitiesProperties);
931         MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
932
933         if(MapUtils.isNotEmpty(capabilitiesProperties) || MapUtils.isNotEmpty(calculatedCapabilitiesProperties )) {
934             StorageOperationStatus calculatedResult =
935                     addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
936                             EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
937                             VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabilityProperty,
938                             componentInstance.getUniqueId());
939             if (calculatedResult != StorageOperationStatus.OK) {
940                 return calculatedResult;
941             }
942         }
943         return StorageOperationStatus.OK;
944     }
945     
946     public StorageOperationStatus updateComponentInstanceRequirement(String componentId, String componentInstanceUniqueId, RequirementDataDefinition requirementDataDefinition) {
947         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
948                 .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
949         if (containerVEither.isRight()) {
950             JanusGraphOperationStatus error = containerVEither.right().value();
951             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
952             return StorageOperationStatus.GENERAL_ERROR;
953         }
954         GraphVertex containerV = containerVEither.left().value();
955         return updateComponentInstanceRequirement(componentId, componentInstanceUniqueId, requirementDataDefinition, containerV);
956     }
957
958     private StorageOperationStatus updateComponentInstanceRequirement(String componentId, String componentInstanceUniqueId, RequirementDataDefinition requirementDataDefinition, GraphVertex containerV) {
959         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> existingReqs = getCalculatedRequirements(componentId);
960         if (existingReqs.isRight()) {
961             return existingReqs.right().value();
962         }
963         MapListRequirementDataDefinition componentInstanceRequirementsMap = existingReqs.left().value().getRight().get(componentInstanceUniqueId);
964         if (componentInstanceRequirementsMap == null) {
965             return StorageOperationStatus.NOT_FOUND;
966         }
967         ListRequirementDataDefinition listRequirementDataDefinition = componentInstanceRequirementsMap.getMapToscaDataDefinition().get(requirementDataDefinition.getCapability());
968             
969         listRequirementDataDefinition.getListToscaDataDefinition().stream()
970                 .filter(e -> requirementDataDefinition.getOwnerId().equals(e.getOwnerId()) && requirementDataDefinition.getName().equals(e.getName()))
971                 .forEach(r -> r.setExternal(requirementDataDefinition.isExternal()));
972
973         return updateCalculatedReqOnGraph(componentId, containerV, existingReqs);
974     }
975     
976     private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> getCalculatedRequirements(String componentId) {
977         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> result = null;
978         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
979             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
980         if (containerVEither.isRight()) {
981             JanusGraphOperationStatus error = containerVEither.right().value();
982             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
983             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
984         }
985         if (result == null) {
986             GraphVertex containerV = containerVEither.left().value();
987             result = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
988         }
989         return result;
990     }
991     
992     private StorageOperationStatus updateCalculatedReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult
993             ) {
994         containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
995         Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(containerV);
996         if (updateElement.isRight()) {
997             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
998             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value());
999         }
1000
1001         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1002         Either<GraphVertex, JanusGraphOperationStatus> status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1003         if (status.isRight()) {
1004             JanusGraphOperationStatus error = status.right().value();
1005             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
1006             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1007         }
1008         return StorageOperationStatus.OK;
1009     }
1010     
1011     private StorageOperationStatus addComponentInstanceToscaDataToNodeTypeContainer(NodeType originNodeType,
1012             ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
1013
1014         StorageOperationStatus status;
1015
1016         if(MapUtils.isNotEmpty(originNodeType.getProperties())){
1017             MapPropertiesDataDefinition instProperties =
1018                     new MapPropertiesDataDefinition(originNodeType.getProperties());
1019             status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_PROPERTIES,
1020                     VertexTypeEnum.INST_PROPERTIES, instProperties, componentInstance.getUniqueId());
1021             if (status != StorageOperationStatus.OK) {
1022                 return status;
1023             }
1024         }
1025
1026         if(MapUtils.isNotEmpty(originNodeType.getAttributes())){
1027             MapAttributesDataDefinition instAttributes =
1028                     new MapAttributesDataDefinition(originNodeType.getAttributes());
1029             status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_ATTRIBUTES,
1030                     VertexTypeEnum.INST_ATTRIBUTES, instAttributes, componentInstance.getUniqueId());
1031             if (status != StorageOperationStatus.OK) {
1032                 return status;
1033             }
1034         }
1035
1036         return addCalculatedCapReqFromNodeType(originNodeType, componentInstance, updatedContainerVertex);
1037     }
1038
1039     public MapArtifactDataDefinition prepareInstDeploymentArtifactPerInstance(Map<String, ArtifactDataDefinition> deploymentArtifacts, String componentInstanceId, User user, String envType) {
1040         if (deploymentArtifacts != null && envType.equals(HEAT_VF_ENV_NAME)) {
1041             Map<String, ArtifactDataDefinition> instDeploymentArtifacts = new HashMap<>();
1042
1043             deploymentArtifacts.entrySet().forEach(e -> {
1044                 ArtifactDataDefinition artifact = e.getValue();
1045                 String type = artifact.getArtifactType();
1046                 if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
1047                     ArtifactDataDefinition artifactEnv = createArtifactPlaceHolderInfo(artifact, componentInstanceId, user, envType);
1048                     instDeploymentArtifacts.put(artifactEnv.getArtifactLabel(), artifactEnv);
1049                 }
1050             });
1051
1052             deploymentArtifacts.putAll(instDeploymentArtifacts);
1053
1054             return new MapArtifactDataDefinition(deploymentArtifacts);
1055
1056         }
1057         return null;
1058     }
1059
1060     @SuppressWarnings({"unchecked"})
1061     private ArtifactDataDefinition createArtifactPlaceHolderInfo(ArtifactDataDefinition artifactHeat, String componentId, User user, String heatEnvType) {
1062         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts();
1063         if (deploymentResourceArtifacts == null) {
1064             log.debug("no deployment artifacts are configured for generated artifacts");
1065             return null;
1066         }
1067         Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(heatEnvType);
1068         if (placeHolderData == null) {
1069             log.debug("no env type {} are configured for generated artifacts", heatEnvType);
1070             return null;
1071         }
1072
1073         String envLabel = (artifactHeat.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
1074
1075         ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
1076
1077         String artifactName = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
1078         String artifactType = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_TYPE);
1079         String artifactDescription = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
1080
1081         artifactInfo.setArtifactDisplayName(artifactName);
1082         artifactInfo.setArtifactLabel(envLabel);
1083         artifactInfo.setArtifactType(artifactType);
1084         artifactInfo.setDescription(artifactDescription);
1085         artifactInfo.setArtifactGroupType(artifactHeat.getArtifactGroupType());
1086         setDefaultArtifactTimeout(artifactHeat.getArtifactGroupType(), artifactInfo);
1087         artifactInfo.setGeneratedFromId(artifactHeat.getUniqueId());
1088         // clone heat parameters in case of heat env only not VF heat env
1089         if (heatEnvType.equals(HEAT_ENV_NAME)) {
1090             artifactInfo.setHeatParameters(artifactHeat.getHeatParameters());
1091         }
1092         setArtifactPlaceholderCommonFields(componentId, user, artifactInfo);
1093
1094         return artifactInfo;
1095     }
1096
1097     public void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDataDefinition artifactInfo) {
1098         if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) {
1099             artifactInfo.setTimeout(defaultHeatTimeout);
1100         } else {
1101             artifactInfo.setTimeout(NON_HEAT_TIMEOUT);
1102         }
1103     }
1104
1105     private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDataDefinition artifactInfo) {
1106         String uniqueId = null;
1107
1108         if (resourceId != null) {
1109             uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
1110             artifactInfo.setUniqueId(uniqueId);
1111         }
1112         artifactInfo.setUserIdCreator(user.getUserId());
1113         String fullName = user.getFullName();
1114         artifactInfo.setUpdaterFullName(fullName);
1115
1116         long time = System.currentTimeMillis();
1117
1118         artifactInfo.setCreatorFullName(fullName);
1119         artifactInfo.setCreationDate(time);
1120
1121         artifactInfo.setLastUpdateDate(time);
1122         artifactInfo.setUserIdLastUpdater(user.getUserId());
1123
1124         artifactInfo.setMandatory(true);
1125     }
1126
1127     /**
1128      * @param originNodeType
1129      * @param componentInstance
1130      * @param updatedContainerVertex
1131      * @return
1132      */
1133     private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
1134
1135         Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilities();
1136         MapListCapabilityDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
1137         StorageOperationStatus calculatedResult;
1138         if (allCalculatedCap != null) {
1139             calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId());
1140
1141             if (calculatedResult != StorageOperationStatus.OK) {
1142                 return calculatedResult;
1143             }
1144         }
1145         Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabilitiesProperties();
1146         if (capabiltiesProperties != null) {
1147             Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), Entry::getValue));
1148             MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
1149             calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabilityProperty, componentInstance.getUniqueId());
1150             if (calculatedResult != StorageOperationStatus.OK) {
1151                 return calculatedResult;
1152             }
1153         }
1154
1155         MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
1156         calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
1157
1158         if (calculatedResult != StorageOperationStatus.OK) {
1159             return calculatedResult;
1160         }
1161
1162         Map<String, ListRequirementDataDefinition> requirements = originNodeType.getRequirements();
1163
1164         MapListRequirementDataDefinition allCalculatedReq = prepareCalculatedRequirementForNodeType(requirements, componentInstance);
1165
1166         StorageOperationStatus status;
1167         if (allCalculatedReq != null) {
1168             status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq, componentInstance.getUniqueId());
1169             if (status != StorageOperationStatus.OK) {
1170                 return status;
1171             }
1172         }
1173         MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
1174         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
1175         return StorageOperationStatus.OK;
1176
1177     }
1178
1179     public static String createCapPropertyKey(String key, String instanceId) {
1180         StringBuffer sb = new StringBuffer(instanceId);
1181         sb.append(ModelConverter.CAP_PROP_DELIM).append(instanceId).append(ModelConverter.CAP_PROP_DELIM).append(key);
1182         return sb.toString();
1183     }
1184
1185     /**
1186      * 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
1187      *
1188      * @param capabilities
1189      * @param componentInstance
1190      * @return
1191      */
1192     public MapListCapabilityDataDefinition prepareCalculatedCapabiltyForNodeType(Map<String, ListCapabilityDataDefinition> capabilities, ComponentInstanceDataDefinition componentInstance) {
1193         if (capabilities != null) {
1194             MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
1195
1196             populateCapability(capabilities, componentInstance, allCalculatedCap);
1197             return allCalculatedCap;
1198         }
1199         return null;
1200     }
1201
1202     /**
1203      * 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
1204      *
1205      * @param requirements
1206      * @param componentInstance
1207      * @return
1208      */
1209     public MapListRequirementDataDefinition prepareCalculatedRequirementForNodeType(Map<String, ListRequirementDataDefinition> requirements, ComponentInstanceDataDefinition componentInstance) {
1210         if (requirements != null) {
1211             MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
1212
1213             populateRequirement(requirements, componentInstance, allCalculatedReq);
1214             return allCalculatedReq;
1215         }
1216         return null;
1217     }
1218
1219     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstanceDataDefinition componentInstance, List<GroupDefinition> groups, Map<String, List<ArtifactDefinition>> groupInstancesArtifacts) {
1220
1221         StorageOperationStatus result = null;
1222         Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
1223         if (groupInstancesArtifacts != null && CollectionUtils.isNotEmpty(groups)) {
1224             for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts : groupInstancesArtifacts.entrySet()) {
1225                 Optional<GroupDefinition> groupOptional = groups.stream().filter(g -> g.getUniqueId().equals(groupArtifacts.getKey())).findFirst();
1226                 if (groupOptional.isPresent()) {
1227                     GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition((GroupDataDefinition) groupOptional.get(), (ComponentInstanceDataDefinition) componentInstance, null);
1228                     groupInstance.setGroupInstanceArtifacts(groupArtifacts.getValue().stream().map(ArtifactDataDefinition::getUniqueId).collect(Collectors.toList()));
1229                     groupInstance.setGroupInstanceArtifactsUuid(groupArtifacts.getValue().stream().map(ArtifactDataDefinition::getArtifactUUID).collect(Collectors.toList()));
1230                     groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
1231                 }
1232             }
1233         }
1234         if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
1235             result = addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, new MapDataDefinition<>(groupInstanceToCreate), componentInstance.getUniqueId());
1236         }
1237         if (result == null) {
1238             result = StorageOperationStatus.OK;
1239         }
1240         return result;
1241     }
1242
1243     private ComponentInstanceDataDefinition buildComponentInstanceDataDefinition(ComponentInstance resourceInstance, String containerComponentId, String instanceNewName, boolean generateUid, ToscaElement originToscaElement) {
1244         String ciOriginComponentUid = resourceInstance.getComponentUid();
1245
1246         if (!ValidationUtils.validateStringNotEmpty(resourceInstance.getCustomizationUUID())) {
1247             resourceInstance.setCustomizationUUID(generateCustomizationUUID());
1248         }
1249         ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance);
1250
1251         Long creationDate = resourceInstance.getCreationTime();
1252         Long modificationTime;
1253         if (creationDate == null) {
1254             creationDate = System.currentTimeMillis();
1255             modificationTime = creationDate;
1256         } else {
1257             modificationTime = System.currentTimeMillis();
1258         }
1259         dataDefinition.setComponentUid(ciOriginComponentUid);
1260         dataDefinition.setCreationTime(creationDate);
1261         dataDefinition.setModificationTime(modificationTime);
1262         if (StringUtils.isNotEmpty(instanceNewName)) {
1263             dataDefinition.setName(instanceNewName);
1264             resourceInstance.setName(instanceNewName);
1265         }
1266         if (StringUtils.isNotEmpty(dataDefinition.getName()))
1267             dataDefinition.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(dataDefinition.getName()));
1268         dataDefinition.setIcon(resourceInstance.getIcon());
1269         if (generateUid) {
1270             dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(containerComponentId, ciOriginComponentUid, dataDefinition.getNormalizedName()));
1271             resourceInstance.setUniqueId(dataDefinition.getUniqueId());
1272         }
1273         if (StringUtils.isEmpty(dataDefinition.getComponentVersion()) && originToscaElement != null)
1274             dataDefinition.setComponentVersion((String) originToscaElement.getMetadataValue(JsonPresentationFields.VERSION));
1275         if (StringUtils.isEmpty(dataDefinition.getComponentName()) && originToscaElement != null)
1276             dataDefinition.setComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.NAME));
1277         if (originToscaElement != null && dataDefinition.getToscaComponentName() == null)
1278             dataDefinition.setToscaComponentName((String) originToscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
1279         if (dataDefinition.getOriginType() == null && originToscaElement != null) {
1280             ResourceTypeEnum resourceType = originToscaElement.getResourceType();
1281             OriginTypeEnum originType = OriginTypeEnum.findByValue(resourceType.name());
1282             dataDefinition.setOriginType(originType);
1283         }
1284         if (dataDefinition.getOriginType() == OriginTypeEnum.ServiceProxy)
1285             dataDefinition.setIsProxy(true);
1286
1287         return dataDefinition;
1288     }
1289
1290     private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) {
1291         Boolean isUniqueName = true;
1292         try {
1293             isUniqueName = !container.getComponentInstances().values().stream().anyMatch(ci -> ci.getName() != null && ci.getName().equals(instanceName));
1294
1295         } catch (Exception e) {
1296             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage());
1297         }
1298         return isUniqueName;
1299     }
1300
1301     private String buildComponentInstanceName(String instanceSuffixNumber, String instanceName) {
1302         return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
1303     }
1304
1305     public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(Component component, String componentId, RequirementCapabilityRelDef relation) {
1306         List<RequirementCapabilityRelDef> relations = new ArrayList<>();
1307         relations.add(relation);
1308         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(component, componentId, relations);
1309         if (associateResourceInstances.isRight()) {
1310             return Either.right(associateResourceInstances.right().value());
1311         }
1312         return Either.left(associateResourceInstances.left().value().get(0));
1313     }
1314
1315     @SuppressWarnings({"unchecked"})
1316     public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(Component component, String componentId, List<RequirementCapabilityRelDef> relations) {
1317
1318         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
1319             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1320         if (containerVEither.isRight()) {
1321             JanusGraphOperationStatus error = containerVEither.right().value();
1322             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1323             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1324         }
1325         GraphVertex containerV = containerVEither.left().value();
1326         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1327         if (capResult.isRight()) {
1328             return Either.right(capResult.right().value());
1329
1330         }
1331         Map<String, MapListCapabilityDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
1332
1333         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1334         if (capResult.isRight()) {
1335             return Either.right(capResult.right().value());
1336
1337         }
1338         Map<String, MapListCapabilityDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
1339
1340         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1341         if (reqResult.isRight()) {
1342             return Either.right(reqResult.right().value());
1343         }
1344         Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1345
1346         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1347         if (reqResult.isRight()) {
1348             return Either.right(reqResult.right().value());
1349         }
1350         Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
1351
1352         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1353         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1354
1355         StorageOperationStatus status;
1356         List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
1357         for (RequirementCapabilityRelDef relation : relations) {
1358             List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
1359             String fromNode = relation.getFromNode();
1360             String toNode = relation.getToNode();
1361             List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
1362             if (relationships == null || relationships.isEmpty()) {
1363                 BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1364                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode);
1365                 loggerSupportability.log(LogLevel.INFO,LoggerSupportabilityActions.CREATE_RELATION.getName(),"componentId: "+componentId+" No requirement definition sent in order to set the relation between: "+fromNode+" to: "+toNode);
1366                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
1367             }
1368
1369             for (CapabilityRequirementRelationship immutablePair : relationships) {
1370                 String requirement = immutablePair.getRelation().getRequirement();
1371
1372                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode, immutablePair.getRelation(), relation.isOriginUI(), calculatedCapabilty, calculatedRequirement,
1373                         fullFilledCapabilty, fullfilledRequirement, compositionDataDefinition, containerV.getUniqueId());
1374
1375                 if (associateRes.isRight()) {
1376                     status = associateRes.right().value();
1377                     BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1378                     loggerSupportability.log(LogLevel.INFO,LoggerSupportabilityActions.CREATE_RELATIONS.name(),
1379                         StatusCode.ERROR,"missing relationship: "+fromNode,"ComopnentId: "+componentId);
1380                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}", fromNode, toNode, status);
1381                     return Either.right(status);
1382                 }
1383
1384                 RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) associateRes.left().value().get(JsonPresentationFields.RELATIONSHIP);
1385                 RelationshipImpl relationshipImplResult = new RelationshipImpl();
1386                 relationshipImplResult.setType(relationshipInstData.getType());
1387                 RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
1388                 requirementAndRelationshipPair.setCapability(immutablePair.getRelation().getCapability());
1389                 requirementAndRelationshipPair.setRequirement(immutablePair.getRelation().getRequirement());
1390                 requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
1391                 requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
1392                 requirementAndRelationshipPair.setCapabilityUid(immutablePair.getRelation().getCapabilityUid());
1393                 requirementAndRelationshipPair.setRequirementUid(immutablePair.getRelation().getRequirementUid());
1394                 requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
1395                 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
1396                 capReqRel.setRelation(requirementAndRelationshipPair);
1397                 capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPABILITY));
1398                 capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
1399                 relationshipsResult.add(capReqRel);
1400                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
1401                 status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
1402                 if (status != StorageOperationStatus.OK) {
1403                     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());
1404                     return Either.right(status);
1405                 }
1406                 status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
1407                 if (status != StorageOperationStatus.OK) {
1408                     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());
1409                     return Either.right(status);
1410                 }
1411             }
1412             RequirementCapabilityRelDef reqCapRelDef = new RequirementCapabilityRelDef(relation);
1413             reqCapRelDef.setRelationships(relationshipsResult);
1414             relationsList.add(reqCapRelDef);
1415         }
1416         status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1417         if (status != StorageOperationStatus.OK) {
1418             return Either.right(status);
1419         }
1420         return Either.left(relationsList);
1421     }
1422
1423     private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV, Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult,
1424                                                                        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult, Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
1425                                                                        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
1426         containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1427         Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(containerV);
1428         if (updateElement.isRight()) {
1429             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId, updateElement.right().value());
1430             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value());
1431         }
1432         // update cap/req jsons, fulfilled cap/req jsons!!!!!
1433         Either<GraphVertex, JanusGraphOperationStatus> status;
1434         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
1435         status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1436         if (status.isRight()) {
1437             JanusGraphOperationStatus error = status.right().value();
1438             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(), error);
1439             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1440         }
1441
1442         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1443         status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1444         if (status.isRight()) {
1445             JanusGraphOperationStatus error = status.right().value();
1446             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(), error);
1447             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1448         }
1449
1450         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
1451         status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1452         if (status.isRight()) {
1453             JanusGraphOperationStatus error = status.right().value();
1454             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(), error);
1455             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1456         }
1457
1458         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
1459         status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1460         if (status.isRight()) {
1461             JanusGraphOperationStatus error = status.right().value();
1462             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}", containerV.getUniqueId(), error);
1463             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1464         }
1465         return StorageOperationStatus.OK;
1466     }
1467
1468     @SuppressWarnings({"unchecked"})
1469     public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, RequirementCapabilityRelDef requirementDef) {
1470         if (requirementDef.getRelationships() == null) {
1471             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
1472             return Either.right(StorageOperationStatus.BAD_REQUEST);
1473         }
1474
1475         String fromResInstanceUid = requirementDef.getFromNode();
1476         String toResInstanceUid = requirementDef.getToNode();
1477
1478         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
1479             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1480         if (containerVEither.isRight()) {
1481             JanusGraphOperationStatus error = containerVEither.right().value();
1482             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1483             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1484         }
1485         GraphVertex containerV = containerVEither.left().value();
1486
1487         // DE191707 - validations
1488         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1489         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1490         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1491         ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
1492         if (ciFrom == null) {
1493             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
1494             return Either.right(StorageOperationStatus.NOT_FOUND);
1495
1496         }
1497         ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
1498         if (ciFrom == ciTo) {
1499             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
1500             return Either.right(StorageOperationStatus.NOT_FOUND);
1501
1502         }
1503         Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
1504
1505         List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
1506         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1507         if (capResult.isRight()) {
1508             return Either.right(capResult.right().value());
1509         }
1510         Map<String, MapListCapabilityDataDefinition> calculatedCapability = capResult.left().value().getRight();
1511
1512         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1513         if (capResult.isRight()) {
1514             return Either.right(capResult.right().value());
1515
1516         }
1517         Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1518
1519         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1520         if (reqResult.isRight()) {
1521             return Either.right(reqResult.right().value());
1522         }
1523         Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1524
1525         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1526         if (reqResult.isRight()) {
1527             return Either.right(reqResult.right().value());
1528         }
1529         Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1530
1531         for (CapabilityRequirementRelationship relationPair : relationPairList) {
1532             Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
1533             boolean isDeleted = false;
1534             while (iterator.hasNext()) {
1535                 Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
1536                 RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
1537                 if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson.getUniqueId().equals(relationPair.getRelation().getId())) {
1538                     if (relationPair.getRelation().equalsTo(relationInJson)) {
1539                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationInJson.getType(), relationInJson.getCapabilityOwnerId(),
1540                                 relationInJson.getRequirementOwnerId());
1541                         iterator.remove();
1542
1543                         // update calculated cap/req
1544                         StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability, toResInstanceUid, relationInJson, relationPair);
1545                         if (status != StorageOperationStatus.OK) {
1546                             return Either.right(status);
1547                         }
1548                         status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid, relationInJson, relationPair);
1549                         if (status != StorageOperationStatus.OK) {
1550                             return Either.right(status);
1551                         }
1552                         isDeleted = true;
1553                     }
1554                 }
1555             }
1556             if (!isDeleted) {
1557                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ", toResInstanceUid, componentId, relationPair.getCapability(),
1558                         relationPair.getRelation().getCapabilityOwnerId(), relationPair.getRelation().getRequirementOwnerId());
1559                 return Either.right(StorageOperationStatus.NOT_FOUND);
1560             }
1561         }
1562         StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
1563         if (status != StorageOperationStatus.OK) {
1564             return Either.right(status);
1565         }
1566         status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
1567         if (status != StorageOperationStatus.OK) {
1568             return Either.right(status);
1569         }
1570
1571         // update jsons
1572         // update metadata of container and composition json
1573         status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1574         if (status != StorageOperationStatus.OK) {
1575             return Either.right(status);
1576         }
1577
1578         return Either.left(requirementDef);
1579     }
1580
1581     /**
1582      * Retrieves fulfilled requirement according to relation and received predicate
1583      *
1584      * @param componentId
1585      * @param instanceId
1586      * @param foundRelation
1587      * @param predicate
1588      * @return
1589      */
1590     public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation,
1591                                                                                                        BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
1592
1593         Either<RequirementDataDefinition, StorageOperationStatus> result = null;
1594         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
1595         MapListRequirementDataDefinition reqMapOfLists = null;
1596         Optional<RequirementDataDefinition> foundRequirement;
1597         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1598         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
1599             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1600         if (containerVEither.isRight()) {
1601             JanusGraphOperationStatus error = containerVEither.right().value();
1602             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1603             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1604         }
1605         if (result == null) {
1606             GraphVertex containerV = containerVEither.left().value();
1607             reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1608             if (reqFullResult.isRight()) {
1609                 result = Either.right(reqFullResult.right().value());
1610             }
1611         }
1612         if (result == null) {
1613             Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1614             reqMapOfLists = fulfilledRequirement.get(instanceId);
1615             if (reqMapOfLists == null) {
1616                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1617             }
1618         }
1619         if (result == null && reqMapOfLists != null) {
1620             for (ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()) {
1621                 foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req)).findFirst();
1622                 if (foundRequirement.isPresent()) {
1623                     result = Either.left(foundRequirement.get());
1624                 }
1625             }
1626         }
1627         return result;
1628     }
1629
1630     /**
1631      * Retrieves fulfilled capability according to relation and received predicate
1632      *
1633      * @param componentId
1634      * @param instanceId
1635      * @param foundRelation
1636      * @param predicate
1637      * @return
1638      */
1639     public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId, RequirementCapabilityRelDef foundRelation,
1640                                                                                                      BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
1641
1642         Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
1643         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = null;
1644         MapListCapabilityDataDefinition capMapOfLists = null;
1645         Optional<CapabilityDataDefinition> foundRequirement;
1646
1647         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1648         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
1649             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1650         if (containerVEither.isRight()) {
1651             JanusGraphOperationStatus error = containerVEither.right().value();
1652             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1653             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1654         }
1655         if (result == null) {
1656             GraphVertex containerV = containerVEither.left().value();
1657             capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1658             if (capFullResult.isRight()) {
1659                 result = Either.right(capFullResult.right().value());
1660             }
1661         }
1662         if (result == null) {
1663             Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1664             capMapOfLists = fulfilledCapability.get(instanceId);
1665             if (capMapOfLists == null) {
1666                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1667             }
1668         }
1669         if (result == null && capMapOfLists != null) {
1670             for (ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()) {
1671                 foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap)).findFirst();
1672                 if (foundRequirement.isPresent()) {
1673                     result = Either.left(foundRequirement.get());
1674                 }
1675             }
1676         }
1677         return result;
1678     }
1679
1680     private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1681                                                                                    RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1682         StorageOperationStatus status;
1683         String hereIsTheKey = null;
1684         MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
1685         if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
1686             // move from fulfilled
1687             status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1688         } else {
1689             hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1690             ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1691             Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream()
1692                     .filter(req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())).findFirst();
1693
1694             if (requirementOptional.isPresent()) {
1695
1696                 RequirementDataDefinition requirement = requirementOptional.get();
1697                 String leftOccurrences = requirement.getLeftOccurrences();
1698                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
1699                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
1700                     ++leftIntValue;
1701                     requirement.setLeftOccurrences(String.valueOf(leftIntValue));
1702                 }
1703                 if (relationship != null) {
1704                     relationship.setRequirement(requirement);
1705                 }
1706                 status = StorageOperationStatus.OK;
1707             } else {
1708                 // move from fulfilled
1709                 status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey, relationship);
1710             }
1711         }
1712         return status;
1713     }
1714
1715     private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabilityDataDefinition> calculatedCapability, Map<String, MapListCapabilityDataDefinition> fullFilledCapability, String toResInstanceUid,
1716                                                                                 RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
1717         StorageOperationStatus status;
1718         String hereIsTheKey = null;
1719         MapListCapabilityDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
1720         if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
1721             // move from fulfilled
1722             status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1723         } else {
1724             hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1725             ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1726             Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream().filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
1727                     .findFirst();
1728
1729             if (capabilityOptional.isPresent()) {
1730
1731                 CapabilityDataDefinition capability = capabilityOptional.get();
1732                 String leftOccurrences = capability.getLeftOccurrences();
1733                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1734                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
1735                     ++leftIntValue;
1736                     capability.setLeftOccurrences(String.valueOf(leftIntValue));
1737                 }
1738                 if (relationship != null) {
1739                     relationship.setCapability(capability);
1740                 }
1741                 status = StorageOperationStatus.OK;
1742             } else {
1743                 // move from fulfilled
1744                 status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
1745             }
1746         }
1747         return status;
1748     }
1749
1750     private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabilityDataDefinition> calculatedCapability, Map<String, MapListCapabilityDataDefinition> fullFilledCapability, String toResInstanceUid,
1751                                                                RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1752         MapListCapabilityDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
1753         if (capByInstance == null) {
1754             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
1755             return StorageOperationStatus.GENERAL_ERROR;
1756         }
1757         if (null == hereIsTheKey)
1758             hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
1759         if (null == hereIsTheKey) {
1760             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(), toResInstanceUid);
1761             return StorageOperationStatus.GENERAL_ERROR;
1762         }
1763         ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
1764         Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
1765         boolean found = false;
1766         while (iterator.hasNext()) {
1767             CapabilityDataDefinition cap = iterator.next();
1768             if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
1769                 found = true;
1770                 iterator.remove();
1771                 // return to calculated list
1772                 String leftOccurrences = cap.getLeftOccurrences();
1773                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1774                 ++leftIntValue;
1775                 cap.setLeftOccurrences(String.valueOf(leftIntValue));
1776
1777                 MapListCapabilityDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
1778                 if (mapListCapaDataDef == null) {
1779                     mapListCapaDataDef = new MapListCapabilityDataDefinition();
1780                 }
1781                 ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
1782                 if (findByKey == null) {
1783                     findByKey = new ListCapabilityDataDefinition();
1784                     mapListCapaDataDef.put(hereIsTheKey, findByKey);
1785                 }
1786                 findByKey.add(cap);
1787                 if (relationship != null)
1788                     relationship.setCapability(cap);
1789                 break;
1790             }
1791         }
1792         if (!found) {
1793             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getCapabilityOwnerId(), toResInstanceUid);
1794             return StorageOperationStatus.GENERAL_ERROR;
1795         }
1796         return StorageOperationStatus.OK;
1797     }
1798
1799     private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement, String fromResInstanceUid,
1800                                                                  RelationshipInstDataDefinition relation, String hereIsTheKey, CapabilityRequirementRelationship relationship) {
1801         MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
1802         if (reqByInstance == null) {
1803             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
1804             return StorageOperationStatus.GENERAL_ERROR;
1805         }
1806         if (null == hereIsTheKey)
1807             hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
1808         if (null == hereIsTheKey) {
1809             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(), fromResInstanceUid);
1810             return StorageOperationStatus.GENERAL_ERROR;
1811         }
1812         ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
1813         Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
1814         boolean found = false;
1815         while (iterator.hasNext()) {
1816             RequirementDataDefinition req = iterator.next();
1817             if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId().equals(relation.getRequirementId())) {
1818                 found = true;
1819                 iterator.remove();
1820                 // return to calculated list
1821                 String leftOccurrences = req.getLeftOccurrences();
1822                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
1823                 ++leftIntValue;
1824                 req.setLeftOccurrences(String.valueOf(leftIntValue));
1825
1826                 MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
1827                 if (mapListReqDataDef == null) {
1828                     mapListReqDataDef = new MapListRequirementDataDefinition();
1829                 }
1830                 ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
1831                 if (findByKey == null) {
1832                     findByKey = new ListRequirementDataDefinition();
1833                     mapListReqDataDef.put(hereIsTheKey, findByKey);
1834                 }
1835                 findByKey.add(req);
1836                 if (relationship != null)
1837                     relationship.setRequirement(req);
1838                 break;
1839             }
1840         }
1841         if (!found) {
1842             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey, relation.getRequirementOwnerId(), fromResInstanceUid);
1843             return StorageOperationStatus.GENERAL_ERROR;
1844         }
1845         return StorageOperationStatus.OK;
1846
1847     }
1848
1849     public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
1850         ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
1851
1852         if (componentInstance == null) {
1853             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
1854             return StorageOperationStatus.NOT_FOUND;
1855         }
1856         UUID uuid = UUID.randomUUID();
1857         componentInstance.setCustomizationUUID(uuid.toString());
1858
1859         return StorageOperationStatus.OK;
1860     }
1861
1862     public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair, boolean originUI,
1863                                                                                                                                       Map<String, MapListCapabilityDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty,
1864                                                                                                                                       Map<String, MapListRequirementDataDefinition> fullfilledRequirement, CompositionDataDefinition compositionDataDefinition, String containerId) {
1865         String requirement = relationPair.getRequirement();
1866         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1867
1868         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, containerId, requirement);
1869
1870         ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
1871         if (fromResourceInstData == null) {
1872             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
1873             return Either.right(StorageOperationStatus.NOT_FOUND);
1874         }
1875         ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
1876         if (toResourceInstData == null) {
1877             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
1878             return Either.right(StorageOperationStatus.NOT_FOUND);
1879         }
1880
1881         Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData, toResourceInstData, relationPair, originUI, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty,
1882                 fullfilledRequirement, containerId);
1883         if (reqVsCap.isRight()) {
1884             StorageOperationStatus status = reqVsCap.right().value();
1885             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement, fromResInstanceUid, toResInstanceUid, status);
1886             return Either.right(status);
1887         }
1888         Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
1889
1890         // add to json new relations
1891         compositionDataDefinition.addRelation(((RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(), (RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP));
1892
1893         return Either.left(relationship);
1894     }
1895
1896     private Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(GraphVertex containerV, EdgeLabelEnum capLabel) {
1897
1898         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, JanusGraphOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(containerV, capLabel);
1899         if (calculatedCapabiltyEither.isRight()) {
1900             JanusGraphOperationStatus error = calculatedCapabiltyEither.right().value();
1901             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
1902             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1903         }
1904         Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
1905         return Either.left(calculatedCapabilty);
1906     }
1907
1908     private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(GraphVertex containerV, EdgeLabelEnum reqLabel) {
1909         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, JanusGraphOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(containerV, reqLabel);
1910         if (calculatedRequirementEither.isRight()) {
1911             JanusGraphOperationStatus error = calculatedRequirementEither.right().value();
1912             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(), error);
1913             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1914         }
1915         Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
1916         return Either.left(calculatedRequirement);
1917     }
1918
1919     @SuppressWarnings("unchecked")
1920     private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance,
1921                                                                                                                                           RelationshipInfo relationPair, boolean originUI, Map<String, MapListCapabilityDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement,
1922                                                                                                                                           Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty, Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
1923         String type = relationPair.getRelationship().getType();
1924         // capability
1925
1926         String toInstId = toResInstance.getUniqueId();
1927         MapListCapabilityDataDefinition mapListCapabilityDataDefinition = calculatedCapabilty.get(toInstId);
1928         Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
1929
1930         if (mapListCapabilityDataDefinition == null) {
1931             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId, containerId);
1932             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1933         }
1934         ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabilityDataDefinition.getMapToscaDataDefinition().get(type);
1935         if (listCapabilityDataDefinition == null) {
1936             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type, toInstId, containerId);
1937             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1938         }
1939         CapabilityDataDefinition capabilityForRelation = null;
1940         Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
1941         while (iteratorCap.hasNext()) {
1942             CapabilityDataDefinition cap = iteratorCap.next();
1943             if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
1944                 capabilityForRelation = cap;
1945                 capReqRelationship.put(JsonPresentationFields.CAPABILITY, (T) capabilityForRelation);
1946                 String leftOccurrences = cap.getLeftOccurrences();
1947                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
1948                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
1949                     if (leftIntValue > 0) {
1950                         --leftIntValue;
1951                         capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
1952                         if (leftIntValue == 0) {
1953                             // remove from calculated
1954                             iteratorCap.remove();
1955                             // move to fulfilled
1956                             MapListCapabilityDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
1957                             if (mapListCapabiltyFullFilledInst == null) {
1958                                 mapListCapabiltyFullFilledInst = new MapListCapabilityDataDefinition();
1959                                 fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
1960                             }
1961
1962                             ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
1963                             if (listCapabilityFull == null) {
1964                                 listCapabilityFull = new ListCapabilityDataDefinition();
1965                                 mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
1966                             }
1967                             listCapabilityFull.add(capabilityForRelation);
1968                         }
1969                         break;
1970                     } else {
1971                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.", capabilityForRelation.getType(), toInstId, containerId);
1972                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1973                     }
1974                 }
1975             }
1976         }
1977         if (capabilityForRelation == null) {
1978             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId, containerId);
1979             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1980         }
1981
1982         // requirements
1983         String fromInstId = fromResInstance.getUniqueId();
1984         MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
1985         if (mapListRequirementDataDefinition == null) {
1986             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId, containerId);
1987             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1988         }
1989         ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
1990         if (listRequirementDataDefinition == null) {
1991             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type, fromInstId, containerId);
1992             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1993         }
1994
1995         RequirementDataDefinition requirementForRelation = null;
1996         Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
1997         while (iteratorReq.hasNext()) {
1998             RequirementDataDefinition req = iteratorReq.next();
1999             if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
2000                 requirementForRelation = req;
2001                 capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T) requirementForRelation);
2002                 String leftOccurrences = req.getLeftOccurrences();
2003                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
2004                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
2005                     if (leftIntValue > 0) {
2006                         --leftIntValue;
2007                         req.setLeftOccurrences(String.valueOf(leftIntValue));
2008                         if (leftIntValue == 0) {
2009                             // remove from calculated
2010                             iteratorReq.remove();
2011                             // move to fulfilled
2012                             MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
2013                             if (mapListRequirementFullFilledInst == null) {
2014                                 mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
2015                                 fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
2016                             }
2017
2018                             ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
2019                             if (listRequirementFull == null) {
2020                                 listRequirementFull = new ListRequirementDataDefinition();
2021                                 mapListRequirementFullFilledInst.put(type, listRequirementFull);
2022                             }
2023                             listRequirementFull.add(requirementForRelation);
2024                         }
2025                         break;
2026                     } else {
2027                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.", requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
2028                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2029                     }
2030                 }
2031             }
2032         }
2033         if (requirementForRelation == null) {
2034             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch requirement for type {} for instance {} in container {}.", type, toInstId, containerId);
2035             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2036         }
2037         if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
2038             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No macth for capability from type {} and requirement {} from {} to {} in container {}.", capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId, toInstId,
2039                     containerId);
2040             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2041         }
2042
2043         RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair, originUI);
2044         if (requirementForRelation.getRelationship() != null)
2045             relationshipTypeData.setType(requirementForRelation.getRelationship());
2046         capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T) relationshipTypeData);
2047         return Either.left(capReqRelationship);
2048     }
2049
2050     private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair, boolean originUI) {
2051
2052         RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
2053         relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
2054
2055         relationshipInstData.setType(relationPair.getRelationship().getType());
2056         Long creationDate = System.currentTimeMillis();
2057         relationshipInstData.setCreationTime(creationDate);
2058         relationshipInstData.setModificationTime(creationDate);
2059         relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
2060         relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
2061         relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
2062         relationshipInstData.setRequirementId(relationPair.getRequirementUid());
2063         relationshipInstData.setFromId(fromResInstanceUid);
2064         relationshipInstData.setToId(toInstId);
2065         relationshipInstData.setRequirement(relationPair.getRequirement());
2066         relationshipInstData.setCapability(relationPair.getCapability());
2067         relationshipInstData.setOriginUI(originUI);
2068
2069         return relationshipInstData;
2070     }
2071
2072     public <T extends Component> Map<String, ComponentInstanceDataDefinition> associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, T> componentInstanceTMap, GraphVertex containerVertex, boolean allowDeleted, boolean isUpdateCsar) {
2073
2074         String containerId = containerComponent.getUniqueId();
2075         Map<String, ComponentInstanceDataDefinition> instancesJsonData;
2076         Either<GraphVertex, JanusGraphOperationStatus> updateElement = null;
2077         if (!validateInstanceNames(componentInstanceTMap)) {
2078             throw new StorageException(StorageOperationStatus.INCONSISTENCY);
2079         }
2080         if (!allowDeleted) {
2081             if (!validateDeletedResources(componentInstanceTMap)) {
2082                 throw new StorageException(StorageOperationStatus.INCONSISTENCY);
2083             }
2084         }
2085         instancesJsonData = convertToComponentInstanceDataDefinition(componentInstanceTMap, containerId, isUpdateCsar);
2086
2087         if (MapUtils.isNotEmpty(instancesJsonData)) {
2088             containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
2089             Map<String, CompositionDataDefinition> compositions = new HashMap<>();
2090             CompositionDataDefinition composition = new CompositionDataDefinition();
2091             composition.setComponentInstances(instancesJsonData);
2092             compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
2093             containerVertex.setJson(compositions);
2094             updateElement = janusGraphDao.updateVertex(containerVertex);
2095             if (updateElement.isRight()) {
2096                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ", containerComponent.getName());
2097                 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
2098             }
2099         }
2100         if (updateElement != null) {
2101             GraphVertex vertexC = updateElement.left().value();
2102             instancesJsonData.entrySet().forEach(i -> createInstanceEdge(vertexC, i.getValue()));
2103         }
2104         return instancesJsonData;
2105     }
2106
2107     private <T extends Component> Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, T> componentInstanceTMap, String containerId, boolean isUpdateCsar) {
2108
2109         Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
2110         for (Entry<ComponentInstance, T> entry : componentInstanceTMap.entrySet()) {
2111             ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, !isUpdateCsar || entry.getKey().isCreatedFromCsar(), ModelConverter.convertToToscaElement(entry.getValue()));
2112             instances.put(instance.getUniqueId(), instance);
2113         }
2114         return instances;
2115     }
2116
2117     private <T extends Component> boolean validateDeletedResources(Map<ComponentInstance, T> resourcesInstancesMap) {
2118         boolean result = true;
2119         for (Component component : resourcesInstancesMap.values()) {
2120             if (component.getIsDeleted() != null && component.getIsDeleted()) {
2121                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", component.getName());
2122                 result = false;
2123                 break;
2124             }
2125         }
2126         return result;
2127     }
2128
2129     private <T extends Component> boolean validateInstanceNames(Map<ComponentInstance, T> resourcesInstancesMap) {
2130         boolean result = true;
2131         Set<String> names = new HashSet<>();
2132         for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
2133             if (StringUtils.isEmpty(instance.getName())) {
2134                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
2135                     "Component instance {} name is empty. Cannot add component instance. ", instance.getUniqueId());
2136                 result = false;
2137                 break;
2138             } else if (names.contains(instance.getName())) {
2139                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
2140                     "Component instance with the name {} already exsists. Cannot add component instance. ",
2141                     instance.getName());
2142                 result = false;
2143                 break;
2144             } else {
2145                 names.add(instance.getName());
2146             }
2147         }
2148         return result;
2149     }
2150
2151     public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
2152         return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
2153     }
2154
2155     public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts) {
2156         return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS);
2157     }
2158
2159     public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId, Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexType) {
2160         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
2161             .getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
2162         if (metadataVertex.isRight()) {
2163             JanusGraphOperationStatus status = metadataVertex.right().value();
2164             if (status == JanusGraphOperationStatus.NOT_FOUND) {
2165                 status = JanusGraphOperationStatus.INVALID_ID;
2166             }
2167             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
2168         }
2169         MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
2170         return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
2171
2172     }
2173
2174     @SuppressWarnings({"unchecked"})
2175     public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
2176         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
2177             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
2178         if (metadataVertex.isRight()) {
2179             JanusGraphOperationStatus status = metadataVertex.right().value();
2180             if (status == JanusGraphOperationStatus.NOT_FOUND) {
2181                 status = JanusGraphOperationStatus.INVALID_ID;
2182             }
2183             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
2184         }
2185         GraphVertex metaVertex = metadataVertex.left().value();
2186         Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
2187         CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
2188         StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
2189         if (status != StorageOperationStatus.OK) {
2190             log.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
2191             return status;
2192         }
2193         Either<GraphVertex, JanusGraphOperationStatus> updateVertex = janusGraphDao.updateVertex(metaVertex);
2194         if (updateVertex.isRight()) {
2195             log.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
2196             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateVertex.right().value());
2197         }
2198         return StorageOperationStatus.OK;
2199     }
2200
2201     public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
2202         if (groupInstances != null) {
2203             Either<Map<String, MapGroupsDataDefinition>, JanusGraphOperationStatus> dataFromGraph = getDataFromGraph(componentId, EdgeLabelEnum.INST_GROUPS);
2204             if (dataFromGraph.isRight()) {
2205                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
2206             }
2207             MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
2208             if (grInstPerInstance == null) {
2209                 log.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
2210                 return StorageOperationStatus.NOT_FOUND;
2211             }
2212             for (String instGroupForUpdate : groupInstances) {
2213                 GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
2214                 if (groupInst == null) {
2215                     log.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
2216                     continue;
2217                 }
2218                 UUID uuid = UUID.randomUUID();
2219                 groupInst.setCustomizationUUID(uuid.toString());
2220             }
2221
2222         }
2223         return StorageOperationStatus.OK;
2224     }
2225
2226     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance, List<GroupInstance> groupInstances) {
2227
2228         return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
2229                 new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(GroupInstanceDataDefinition::getName, gi -> gi))), componentInstance.getUniqueId());
2230     }
2231
2232     public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance, Map<String, ArtifactDefinition> deploymentArtifacts) {
2233
2234         return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts),
2235                 componentInstance.getUniqueId());
2236     }
2237
2238     public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
2239
2240         List<String> pathKeys = new ArrayList<>();
2241         pathKeys.add(componentInstanceId);
2242         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
2243     }
2244
2245     public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, String capabilityPropertyKey, ComponentInstanceProperty property) {
2246         List<String> pathKeys = new ArrayList<>();
2247         pathKeys.add(componentInstanceId);
2248         pathKeys.add(capabilityPropertyKey);
2249         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
2250     }
2251
2252     public StorageOperationStatus overrideComponentCapabilitiesProperties(Component containerComponent, Map<String, MapCapabilityProperty> capabilityPropertyMap) {
2253         return overrideToscaDataOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilityPropertyMap);
2254     }
2255
2256     public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) {
2257         List<String> pathKeys = new ArrayList<>();
2258         pathKeys.add(componentInstanceId);
2259         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
2260     }
2261
2262     public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) {
2263         List<String> pathKeys = new ArrayList<>();
2264         pathKeys.add(componentInstanceId);
2265         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
2266     }
2267
2268     public StorageOperationStatus updateComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute property){
2269         List<String> pathKeys = new ArrayList<>();
2270         pathKeys.add(componentInstanceId);
2271         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, property, pathKeys, JsonPresentationFields.NAME);
2272     }
2273
2274     public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute attribute){
2275         List<String> pathKeys = new ArrayList<>();
2276         pathKeys.add(componentInstanceId);
2277         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, attribute, pathKeys, JsonPresentationFields.NAME);
2278     }
2279
2280     public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2281
2282         List<String> pathKeys = new ArrayList<>();
2283         pathKeys.add(componentInstanceId);
2284         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
2285     }
2286
2287     public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) {
2288         List<String> pathKeys = new ArrayList<>();
2289         pathKeys.add(componentInstanceId);
2290         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME);
2291     }
2292
2293     public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) {
2294         List<String> pathKeys = new ArrayList<>();
2295         pathKeys.add(componentInstanceId);
2296         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME);
2297     }
2298
2299     public StorageOperationStatus createInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
2300         String instUniqueId = componentInstance.getUniqueId();
2301
2302         // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
2303         StorageOperationStatus result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(), instUniqueId).either(v -> StorageOperationStatus.OK,
2304                  DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2305
2306         if (result == StorageOperationStatus.OK && componentInstance.getIsProxy()) {
2307             // create edge between container and service origin
2308             result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
2309                         .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2310         }
2311         return result;
2312     }
2313
2314     public StorageOperationStatus createAllottedOfEdge(String componentId, String instanceId, String serviceUUID) {
2315         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
2316         if (vertexById.isRight()) {
2317             log.debug("Failed to fetch component metadata vertex for id {} error {}", componentId, vertexById.right().value());
2318             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value());
2319         }
2320         GraphVertex metadataVertex = vertexById.left().value();
2321
2322         EnumMap<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
2323         props.put(GraphPropertyEnum.UUID, serviceUUID);
2324         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2325
2326         EnumMap<GraphPropertyEnum, Object> hasNot = new EnumMap<>(GraphPropertyEnum.class);
2327         hasNot.put(GraphPropertyEnum.IS_DELETED, true);
2328
2329         Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
2330             .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props,hasNot, JsonParseFlagEnum.ParseMetadata );
2331         if (byCriteria.isRight()) {
2332             log.debug("Failed to fetch vertex by criteria {} error {}", props, byCriteria.right().value());
2333             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value());
2334         }
2335         List<GraphVertex> vertecies = byCriteria.left().value();
2336         StorageOperationStatus result = StorageOperationStatus.OK;
2337         if (vertecies != null) {
2338             GraphVertex serviceVertex = vertecies.get(0);
2339             //remove previous edges
2340
2341             log.debug("Try to create or update edge between resource {} and service {} ", metadataVertex, serviceVertex.getUniqueId());
2342             // create edge between container and service reference
2343             result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.ALLOTTED_OF, serviceVertex.getUniqueId(), instanceId).either(v -> StorageOperationStatus.OK,
2344                     DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2345         }
2346         return result;
2347     }
2348
2349
2350     public StorageOperationStatus removeInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
2351         String instUniqueId = componentInstance.getUniqueId();
2352
2353         // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
2354         StorageOperationStatus result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(), instUniqueId)
2355                 .either(v -> StorageOperationStatus.OK,
2356                 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2357
2358         if (componentInstance.getIsProxy()) {
2359             // create edge between container and service origin
2360             result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
2361                     .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2362         }
2363         return result;
2364     }
2365
2366     private Either<GraphVertex, JanusGraphOperationStatus> createOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId) {
2367         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
2368         properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
2369
2370         return janusGraphDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties)
2371                 .left()
2372                 .bind(v -> addInstanceToPropertyOnEdge(instUniqueId, v, metadataVertex))
2373                 .right()
2374                 .bind(s -> createInstanceEdge(metadataVertex, edgeLabel, componentUid, instUniqueId, s));
2375     }
2376
2377     private Either<GraphVertex, JanusGraphOperationStatus> removeOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId) {
2378         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
2379         properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
2380
2381         return janusGraphDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties).left().bind(v -> removeInstanceFromPropertyOnEdge(instUniqueId, v, metadataVertex)).right()
2382                 .map(err -> removeInstanceEdgeLogError(metadataVertex, edgeLabel, componentUid, err));
2383     }
2384
2385     private Either<GraphVertex, JanusGraphOperationStatus> addInstanceToPropertyOnEdge(String instUniqueId, Edge edge, GraphVertex metadataVertex) {
2386         // edge exist need to add instance id to list on edge's property
2387         List<String> property = (List<String>) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
2388         if (property == null) {
2389             property = new ArrayList<>();
2390         }
2391         Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
2392         if (!findFirst.isPresent()) {
2393             property.add(instUniqueId);
2394         }
2395         try {
2396             String jsonArr = JsonParserUtils.toJson(property);
2397             log.debug("Update INSTANCES edge property with value {} ", jsonArr);
2398             edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
2399         } catch (IOException e) {
2400             log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e);
2401            return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
2402         }
2403         return Either.left(metadataVertex);
2404     }
2405
2406     private Either<GraphVertex, JanusGraphOperationStatus> removeInstanceFromPropertyOnEdge(String instUniqueId, Edge edge, GraphVertex metadataVertex) {
2407         // edge exist need to add instance id to list on edge's property
2408         List<String> property = (List<String>) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
2409         if (property == null) {
2410             property = new ArrayList<>();
2411         }
2412         Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
2413         if (findFirst.isPresent()) {
2414             property.remove(instUniqueId);
2415         }
2416         if (property.isEmpty()) {
2417             // For last instance need to remove edge
2418             edge.remove();
2419         } else {
2420             try {
2421                 String jsonArr = JsonParserUtils.toJson(property);
2422                 edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
2423             } catch (IOException e) {
2424                 log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e);
2425                return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
2426             }
2427         }
2428         return Either.left(metadataVertex);
2429     }
2430
2431     private Either<GraphVertex, JanusGraphOperationStatus> createInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, String instUniqueId, JanusGraphOperationStatus retrieveEdgeStatus) {
2432         if (retrieveEdgeStatus == JanusGraphOperationStatus.NOT_FOUND) {
2433             // create new edge
2434             Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentUid);
2435             if (vertexById.isRight()) {
2436                 return vertexById;
2437             }
2438             GraphVertex originVertex = vertexById.left().value();
2439             Map<EdgePropertyEnum, Object> edgeProps = new EnumMap<>(EdgePropertyEnum.class);
2440             List<String> instList = new ArrayList<>();
2441             instList.add(instUniqueId);
2442             edgeProps.put(EdgePropertyEnum.INSTANCES, instList);
2443
2444             log.debug("Create new edge {} between {} and {} and properties {} ", edgeLabel, metadataVertex.getUniqueId(), originVertex.getUniqueId(), edgeProps);
2445             JanusGraphOperationStatus
2446                 edgeResult = janusGraphDao
2447                 .createEdge(metadataVertex, originVertex, edgeLabel, edgeProps);
2448             return edgeResult == JanusGraphOperationStatus.OK ? Either.left(metadataVertex) : Either.right(edgeResult);
2449         }
2450         // error
2451         log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
2452         return Either.right(retrieveEdgeStatus);
2453     }
2454
2455     private JanusGraphOperationStatus removeInstanceEdgeLogError(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid, JanusGraphOperationStatus retrieveEdgeStatus) {
2456         if (retrieveEdgeStatus == JanusGraphOperationStatus.NOT_FOUND) {
2457             log.debug("No edge {} to remove between container {} and origin {}", edgeLabel, metadataVertex.getUniqueId(), componentUid);
2458         } else {
2459             // error
2460             log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
2461         }
2462         return retrieveEdgeStatus;
2463     }
2464
2465     public void removeAllAllotedEdges(String uniqueId) {
2466         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(uniqueId);
2467         if (vertexById.isLeft()) {
2468             GraphVertex originVertex = vertexById.left().value();
2469             JanusGraphVertex vertex = originVertex.getVertex();
2470             Iterator<Edge> edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name());
2471             while (edges != null && edges.hasNext()) {
2472                 Edge edge = edges.next();
2473                 edge.remove();
2474             }
2475         }
2476     }
2477 }