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