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