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