Import VSP top. template handling non SDC model
[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         StringBuffer sb = new StringBuffer(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, user);
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, VertexTypeEnum.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                 VertexTypeEnum.CALCULATED_CAP_PROPERTIES, 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                 VertexTypeEnum.CALCULATED_REQUIREMENTS, 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                     VertexTypeEnum.INST_PROPERTIES, 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         User user) {
444
445         Either<TopologyTemplate, StorageOperationStatus> result = null;
446         Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
447         String containerComponentId = container.getUniqueId();
448         CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to create component instance {} in component {}", componentInstance,
449             containerComponentId);
450         String instOriginComponentId = componentInstance.getComponentUid();
451         Either<GraphVertex, JanusGraphOperationStatus> updateElement = null;
452
453         Boolean isDeleted = (Boolean) originToscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED);
454
455         if (!allowDeleted && (isDeleted != null) && isDeleted) {
456             CommonUtility
457                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance", instOriginComponentId);
458             result = Either.right(StorageOperationStatus.INVALID_ID);
459         }
460         Boolean isArchived = originToscaElement.isArchived();
461         if (isArchived != null && isArchived) {
462             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create instance {}. Origin {} component is archived . ",
463                 componentInstance.getName(), originToscaElement.getName());
464             result = Either.right(StorageOperationStatus.COMPONENT_IS_ARCHIVED);
465         }
466
467         if (result == null) {
468             container.addComponentInstance(componentInstance);
469             metadataVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
470             topologyTemplateOperation.fillToscaElementVertexData(metadataVertex, container, JsonParseFlagEnum.ParseAll);
471             updateElement = janusGraphDao.updateVertex(metadataVertex);
472             if (updateElement.isRight()) {
473                 CommonUtility
474                     .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(),
475                         componentInstance.getName());
476                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
477             }
478         }
479         if (result == null) {
480             Either<GraphVertex, StorageOperationStatus> addToscaDataRes = addComponentInstanceToscaDataToContainerComponent(originToscaElement,
481                 componentInstance, updateElement.left().value());
482             if (addToscaDataRes.isRight()) {
483                 result = Either.right(addToscaDataRes.right().value());
484             }
485         }
486         if (result == null) {
487             StorageOperationStatus createInstanceEdge = createInstanceEdge(metadataVertex, componentInstance);
488             result = createInstanceEdge == StorageOperationStatus.OK ? null : Either.right(createInstanceEdge);
489         }
490
491         if (result == null) {
492             updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
493             if (updateContainerComponentRes.isRight()) {
494                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with new component instance {}. ",
495                     container.getName(), componentInstance.getName());
496                 result = Either.right(updateContainerComponentRes.right().value());
497             }
498         }
499         if (result == null) {
500             result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
501         }
502         return result;
503     }
504
505     public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(
506         TopologyTemplate container, ToscaElement originToscaElement, ComponentInstance componentInstance) {
507
508         Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
509         Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
510
511         String containerComponentId = container.getUniqueId();
512         CommonUtility
513             .addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstance,
514                 containerComponentId);
515         ComponentInstanceDataDefinition componentInstanceData = null;
516
517         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
518             .getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
519         if (metadataVertex.isRight()) {
520             JanusGraphOperationStatus status = metadataVertex.right().value();
521             if (status == JanusGraphOperationStatus.NOT_FOUND) {
522                 status = JanusGraphOperationStatus.INVALID_ID;
523             }
524             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
525         }
526         if (result == null) {
527             componentInstanceData = buildComponentInstanceDataDefinition(componentInstance, container.getUniqueId(), componentInstance.getName(),
528                 false, originToscaElement);
529             container.addComponentInstance(componentInstanceData);
530             metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
531             topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
532             Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao
533                 .updateVertex(metadataVertex.left().value());
534             if (updateElement.isRight()) {
535                 CommonUtility
536                     .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(),
537                         componentInstance.getName());
538                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
539             }
540         }
541         if (result == null) {
542             updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
543             if (updateContainerComponentRes.isRight()) {
544                 CommonUtility
545                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {} with updated component instance {}. ",
546                         container.getName(), componentInstance.getName());
547                 result = Either.right(updateContainerComponentRes.right().value());
548             }
549         }
550         if (result == null) {
551             result = Either
552                 .left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceData.getUniqueId()));
553         }
554         return result;
555     }
556
557     public Either<TopologyTemplate, StorageOperationStatus> updateComponentInstanceMetadataOfTopologyTemplate(TopologyTemplate container,
558                                                                                                               ComponentParametersView filter) {
559
560         Either<TopologyTemplate, StorageOperationStatus> result = null;
561         Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
562
563         String containerComponentId = container.getUniqueId();
564         CommonUtility
565             .addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata  of container component {}", containerComponentId);
566
567         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
568             .getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
569         if (metadataVertex.isRight()) {
570             JanusGraphOperationStatus status = metadataVertex.right().value();
571             if (status == JanusGraphOperationStatus.NOT_FOUND) {
572                 status = JanusGraphOperationStatus.INVALID_ID;
573             }
574             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
575         }
576         if (result == null) {
577             metadataVertex.left().value().setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
578             topologyTemplateOperation.fillToscaElementVertexData(metadataVertex.left().value(), container, JsonParseFlagEnum.ParseAll);
579             Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao
580                 .updateVertex(metadataVertex.left().value());
581             if (updateElement.isRight()) {
582                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {}. ", container.getName());
583                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
584             }
585         }
586         if (result == null) {
587             updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId, filter);
588             if (updateContainerComponentRes.isRight()) {
589                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch updated topology template {}. ", container.getName());
590                 result = Either.right(updateContainerComponentRes.right().value());
591             }
592         }
593         if (result == null) {
594             result = Either.left((TopologyTemplate) updateContainerComponentRes.left().value());
595         }
596         return result;
597     }
598
599     public Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> deleteComponentInstanceFromTopologyTemplate(
600         TopologyTemplate container, String componentInstanceId) {
601
602         Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> result = null;
603         Either<ToscaElement, StorageOperationStatus> updateContainerComponentRes = null;
604
605         String containerComponentId = container.getUniqueId();
606         CommonUtility
607             .addRecordToLog(log, LogLevelEnum.TRACE, "Going to update component instance metadata {} of container component {}", componentInstanceId,
608                 containerComponentId);
609
610         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao
611             .getVertexById(container.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
612         if (metadataVertex.isRight()) {
613             JanusGraphOperationStatus status = metadataVertex.right().value();
614             if (status == JanusGraphOperationStatus.NOT_FOUND) {
615                 status = JanusGraphOperationStatus.INVALID_ID;
616             }
617             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
618         }
619         GraphVertex containerV = null;
620         ComponentInstanceDataDefinition removedComponentInstance = null;
621         if (result == null) {
622             removedComponentInstance = container.getComponentInstances().remove(componentInstanceId);
623             containerV = metadataVertex.left().value();
624             StorageOperationStatus status = removeRelationsOfInstance(container, componentInstanceId, containerV);
625             if (status != StorageOperationStatus.OK) {
626                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete relation for component instance {} in container. error {}",
627                     componentInstanceId, container.getUniqueId(), status);
628                 result = Either.right(status);
629             }
630
631             containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
632             topologyTemplateOperation.fillToscaElementVertexData(containerV, container, JsonParseFlagEnum.ParseAll);
633             Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(containerV);
634             if (updateElement.isRight()) {
635                 CommonUtility
636                     .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_UPDATE_TOPOLOGY_TEMPLATE_WITH_NEW_COMPONENT_INSTANCE, container.getName(),
637                         componentInstanceId);
638                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
639             }
640         }
641         if (result == null) {
642             StorageOperationStatus status = deleteComponentInstanceToscaDataFromContainerComponent(containerV, componentInstanceId);
643             if (status != StorageOperationStatus.OK) {
644                 CommonUtility
645                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete data  for instance {} in container {}. error {] ", componentInstanceId,
646                         container.getUniqueId(), status);
647                 return Either.right(status);
648             }
649             ComponentInstance componentInstance = new ComponentInstance(removedComponentInstance);
650             StorageOperationStatus createInstanceEdge = removeInstanceEdge(containerV, componentInstance);
651             result = createInstanceEdge == StorageOperationStatus.OK ? null : Either.right(createInstanceEdge);
652         }
653         if (result == null) {
654             updateContainerComponentRes = topologyTemplateOperation.getToscaElement(containerComponentId);
655             if (updateContainerComponentRes.isRight()) {
656                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
657                     "Failed to fetch updated topology template {} after deleting the component instance {}. ", container.getName(),
658                     componentInstanceId);
659                 result = Either.right(updateContainerComponentRes.right().value());
660             }
661         }
662         if (result == null) {
663             result = Either.left(new ImmutablePair<>((TopologyTemplate) updateContainerComponentRes.left().value(), componentInstanceId));
664         }
665         return result;
666     }
667
668     private StorageOperationStatus removeRelationsOfInstance(TopologyTemplate container, String ciToRemove, GraphVertex containerV) {
669         CompositionDataDefinition composition = container.getCompositions().get(JsonConstantKeysEnum.COMPOSITION.getValue());
670         if (composition != null) {
671             Map<String, RelationshipInstDataDefinition> relations = composition.getRelations();
672             if (MapUtils.isNotEmpty(relations)) {
673                 Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(
674                     containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
675                 if (capResult.isRight()) {
676                     return capResult.right().value();
677
678                 }
679                 Map<String, MapListCapabilityDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
680
681                 Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(
682                     containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
683                 if (capFullResult.isRight()) {
684                     return capFullResult.right().value();
685
686                 }
687                 Map<String, MapListCapabilityDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
688
689                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(
690                     containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
691                 if (reqResult.isRight()) {
692                     return reqResult.right().value();
693                 }
694                 Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
695
696                 Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(
697                     containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
698                 if (reqResult.isRight()) {
699                     return reqResult.right().value();
700                 }
701                 Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
702
703                 Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
704                 while (iterator.hasNext()) {
705                     Entry<String, RelationshipInstDataDefinition> relation = iterator.next();
706                     RelationshipInstDataDefinition relationToDelete = relation.getValue();
707                     if (relationToDelete.getFromId().equals(ciToRemove) || relationToDelete.getToId().equals(ciToRemove)) {
708                         iterator.remove();
709                         if (relationToDelete.getFromId().equals(ciToRemove)) {
710                             updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement, ciToRemove,
711                                 relationToDelete, null);
712                             updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, relationToDelete.getToId(),
713                                 relationToDelete, null);
714                         }
715                         if (relationToDelete.getToId().equals(ciToRemove)) {
716                             updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fullfilledRequirement,
717                                 relationToDelete.getFromId(), relationToDelete, null);
718                             updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapabilty, fullFilledCapabilty, ciToRemove, relationToDelete,
719                                 null);
720                         }
721                     }
722                 }
723                 return updateAllAndCalculatedCapReqOnGraph(container.getUniqueId(), containerV, capResult, capFullResult, reqResult, reqFullResult);
724             }
725         }
726         return StorageOperationStatus.OK;
727     }
728
729     private StorageOperationStatus deleteComponentInstanceToscaDataFromContainerComponent(GraphVertex containerV, String componentInstanceId) {
730         StorageOperationStatus status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES,
731             VertexTypeEnum.CALCULATED_CAPABILITIES, componentInstanceId);
732         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
733             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty  for instance {} in container {}. error {] ",
734                 componentInstanceId, containerV.getUniqueId(), status);
735             return status;
736         }
737         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
738             VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceId);
739         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
740             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
741                 "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceId,
742                 containerV.getUniqueId(), status);
743             return status;
744         }
745         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS,
746             VertexTypeEnum.CALCULATED_REQUIREMENTS, componentInstanceId);
747         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
748             CommonUtility
749                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated requirement  for instance {} in container {}. error {] ",
750                     componentInstanceId, containerV.getUniqueId(), status);
751             return status;
752         }
753         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES,
754             VertexTypeEnum.FULLFILLED_CAPABILITIES, componentInstanceId);
755         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
756             CommonUtility
757                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled capabilities  for instance {} in container {}. error {] ",
758                     componentInstanceId, containerV.getUniqueId(), status);
759             return status;
760         }
761         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS,
762             VertexTypeEnum.FULLFILLED_REQUIREMENTS, componentInstanceId);
763         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
764             CommonUtility
765                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ",
766                     componentInstanceId, containerV.getUniqueId(), status);
767             return status;
768         }
769         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES,
770             componentInstanceId);
771         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
772             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove attributes for instance {} in container {}. error {] ",
773                 componentInstanceId, containerV.getUniqueId(), status);
774             return status;
775         }
776         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES,
777             componentInstanceId);
778         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
779             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove properties for instance {} in container {}. error {] ",
780                 componentInstanceId, containerV.getUniqueId(), status);
781             return status;
782         }
783         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS,
784             componentInstanceId);
785         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
786             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance inputs  for instance {} in container {}. error {] ",
787                 componentInstanceId, containerV.getUniqueId(), status);
788             return status;
789         }
790         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
791             componentInstanceId);
792         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
793             CommonUtility
794                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove fullfilled requirement  for instance {} in container {}. error {] ",
795                     componentInstanceId, containerV.getUniqueId(), status);
796             return status;
797         }
798         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS,
799             VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, componentInstanceId);
800         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
801             CommonUtility
802                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance deployment artifacts  for instance {} in container {}. error {] ",
803                     componentInstanceId, containerV.getUniqueId(), status);
804             return status;
805         }
806         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INSTANCE_ARTIFACTS, VertexTypeEnum.INSTANCE_ARTIFACTS,
807             componentInstanceId);
808         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
809             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance artifacts  for instance {} in container {}. error {] ",
810                 componentInstanceId, containerV.getUniqueId(), status);
811             return status;
812         }
813         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.EXTERNAL_REFS, VertexTypeEnum.EXTERNAL_REF,
814             componentInstanceId);
815         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
816             CommonUtility
817                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove instance external refs  for instance {} in container {}. error {] ",
818                     componentInstanceId, containerV.getUniqueId(), status);
819             return status;
820         }
821         status = deleteToscaDataDeepElementsBlockToToscaElement(containerV, EdgeLabelEnum.INST_INTERFACES,
822             VertexTypeEnum.INST_INTERFACES, componentInstanceId);
823         if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) {
824             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
825                 "Failed to remove service instance interfaces  for instance {} in container {}. " +
826                     "error {] ", componentInstanceId, containerV.getUniqueId(), status);
827             return status;
828         }
829         return StorageOperationStatus.OK;
830     }
831
832     protected Either<GraphVertex, StorageOperationStatus> addComponentInstanceToscaDataToContainerComponent(ToscaElement originToscaElement,
833                                                                                                             ComponentInstanceDataDefinition componentInstance,
834                                                                                                             GraphVertex updatedContainerVertex) {
835
836         Either<GraphVertex, StorageOperationStatus> result;
837         StorageOperationStatus status;
838         if (originToscaElement.getToscaType() == ToscaElementTypeEnum.NODE_TYPE) {
839             status = addComponentInstanceToscaDataToNodeTypeContainer((NodeType) originToscaElement, componentInstance, updatedContainerVertex);
840         } else {
841             status = addComponentInstanceToscaDataToTopologyTemplateContainer((TopologyTemplate) originToscaElement, componentInstance,
842                 updatedContainerVertex);
843         }
844         if (status == StorageOperationStatus.OK) {
845             result = Either.left(updatedContainerVertex);
846         } else {
847             result = Either.right(status);
848         }
849         return result;
850     }
851
852     private StorageOperationStatus addComponentInstanceToscaDataToTopologyTemplateContainer(TopologyTemplate originTopologyTemplate,
853                                                                                             ComponentInstanceDataDefinition componentInstance,
854                                                                                             GraphVertex updatedContainerVertex) {
855
856         StorageOperationStatus status;
857
858         status = addCalculatedCapReqFromTopologyTemplate(originTopologyTemplate, componentInstance, updatedContainerVertex);
859
860         if (status != StorageOperationStatus.OK) {
861
862             return status;
863         }
864
865         MapPropertiesDataDefinition instInputs = new MapPropertiesDataDefinition(originTopologyTemplate.getInputs());
866         MapPropertiesDataDefinition instInputsAsProperties = turnInputsIntoProperties(instInputs);
867
868         status = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS,
869             instInputsAsProperties, componentInstance.getUniqueId());
870         if (status != StorageOperationStatus.OK) {
871             return status;
872         }
873
874         return status;
875     }
876
877     private MapPropertiesDataDefinition turnInputsIntoProperties(MapPropertiesDataDefinition instInput) {
878         if (instInput.getMapToscaDataDefinition() != null) {
879             for (PropertyDataDefinition currProp : instInput.getMapToscaDataDefinition().values()) {
880                 String temp = currProp.getValue();
881                 currProp.setValue(currProp.getDefaultValue());
882                 currProp.setDefaultValue(temp);
883             }
884         }
885         return instInput;
886     }
887
888     private MapListCapabilityDataDefinition prepareCalculatedCapabiltyForTopologyTemplate(
889         Map<String, ListCapabilityDataDefinition> capabilities,
890         ComponentInstanceDataDefinition componentInstance,
891         MapListCapabilityDataDefinition calculatedCap) {
892         MapListCapabilityDataDefinition allCalculatedCap =
893             new MapListCapabilityDataDefinition(calculatedCap);
894         populateCapability(capabilities, componentInstance, allCalculatedCap);
895         return allCalculatedCap;
896     }
897
898     private void populateCapability(Map<String, ListCapabilityDataDefinition> capabilities,
899                                     ComponentInstanceDataDefinition componentInstance,
900                                     MapListCapabilityDataDefinition allCalculatedCap) {
901         capabilities.forEach((key, value) -> {
902             List<CapabilityDataDefinition> listCapabilities = value.getListToscaDataDefinition()
903                 .stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
904             listCapabilities.forEach(cap -> {
905                 cap.setSource(componentInstance.getComponentUid());
906                 cap.addToPath(componentInstance.getUniqueId());
907                 log.debug("enter populateCapability,get Capability OwnerId:{},get componentInstance UniqueId:{}",
908                     cap.getOwnerId(), componentInstance.getUniqueId());
909                 cap.setOwnerId(componentInstance.getUniqueId());
910                 log.debug("enter populateCapability,get Capability OwnerName:{},get componentInstance Name:{}",
911                     cap.getOwnerName(), componentInstance.getName());
912                 if (cap.getOwnerName() == null || cap.getOwnerName().isEmpty()) {
913                     cap.setOwnerName(componentInstance.getName());
914                 }
915                 cap.setLeftOccurrences(cap.getMaxOccurrences());
916                 allCalculatedCap.add(key, cap);
917             });
918         });
919     }
920
921     private MapListRequirementDataDefinition prepareCalculatedRequirementForTopologyTemplate(
922         Map<String, ListRequirementDataDefinition> requirements,
923         ComponentInstanceDataDefinition componentInstance,
924         MapListRequirementDataDefinition calculatedReqs) {
925         MapListRequirementDataDefinition allCalculatedReq =
926             new MapListRequirementDataDefinition(calculatedReqs);
927
928         populateRequirement(requirements, componentInstance, allCalculatedReq);
929         return allCalculatedReq;
930     }
931
932     private void populateRequirement(Map<String, ListRequirementDataDefinition> requirements,
933                                      ComponentInstanceDataDefinition componentInstance,
934                                      MapListRequirementDataDefinition allCalculatedReq) {
935         requirements.forEach((key, value) -> {
936             List<RequirementDataDefinition> listRequirements = value.getListToscaDataDefinition()
937                 .stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
938             listRequirements.forEach(req -> {
939                 req.setSource(componentInstance.getComponentUid());
940                 req.addToPath(componentInstance.getUniqueId());
941                 log.debug("enter populateRequirement,get init Requirements OwnerId:{},get componentInstance UniqueId:{}",
942                     req.getOwnerId(), componentInstance.getUniqueId());
943                 if (req.getOwnerId() == null || req.getOwnerId().isEmpty()) {
944                     req.setOwnerId(componentInstance.getUniqueId());
945                 }
946                 log.debug("enter populateRequirement,get init Requirements OwnerName:{}", req.getOwnerName());
947                 if (req.getOwnerName() == null || req.getOwnerName().isEmpty()) {
948                     req.setOwnerName(componentInstance.getName());
949                 }
950                 req.setLeftOccurrences(req.getMaxOccurrences());
951                 allCalculatedReq.add(key, req);
952             });
953         });
954     }
955
956     private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate,
957                                                                            ComponentInstanceDataDefinition componentInstance,
958                                                                            GraphVertex updatedContainerVertex) {
959         Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
960
961         MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
962         if (calculatedCapabilities != null) {
963             calculatedCapabilities.forEach((key1, value1) -> {
964                 final Map<String, ListCapabilityDataDefinition> mapByType = value1.getMapToscaDataDefinition();
965                 mapByType.forEach((key, value) -> value.getListToscaDataDefinition().stream()
966                     .filter(CapabilityDataDefinition::isExternal)
967                     .forEach(cap -> {
968                         cap.addToPath(componentInstance.getUniqueId());
969                         allCalculatedCap.add(key, cap);
970                     }));
971             });
972         }
973         MapListCapabilityDataDefinition allCaps;
974         Map<String, ListCapabilityDataDefinition> capabilities = originTopologyTemplate.getCapabilities();
975         if (MapUtils.isNotEmpty(capabilities)) {
976             allCaps = prepareCalculatedCapabiltyForTopologyTemplate(capabilities, componentInstance,
977                 allCalculatedCap);
978         } else {
979             allCaps = new MapListCapabilityDataDefinition(allCalculatedCap);
980         }
981         if (!allCaps.isEmpty()) {
982             StorageOperationStatus calculatedCapabilitiesResult =
983                 addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
984                     EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES,
985                     allCaps, componentInstance.getUniqueId());
986             if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
987                 return calculatedCapabilitiesResult;
988             }
989             MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
990             calculatedCapabilitiesResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
991                 EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES,
992                 fullCalculatedCap, componentInstance.getUniqueId());
993             if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
994                 return calculatedCapabilitiesResult;
995             }
996         }
997         Map<String, MapListRequirementDataDefinition> calculatedRequirements =
998             originTopologyTemplate.getCalculatedRequirements();
999         MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
1000         if (calculatedRequirements != null) {
1001             calculatedRequirements.forEach((key, value) -> {
1002                 Map<String, ListRequirementDataDefinition> mapByType =
1003                     value.getMapToscaDataDefinition();
1004                 mapByType.forEach((key1, value1) -> value1.getListToscaDataDefinition().stream()
1005                     .filter(RequirementDataDefinition::isExternal).forEach(req -> {
1006                         req.addToPath(componentInstance.getUniqueId());
1007                         req.setExternal(false);
1008                         allCalculatedReq.add(key1, req);
1009                     }));
1010             });
1011
1012         }
1013
1014         MapListRequirementDataDefinition allReqs;
1015         Map<String, ListRequirementDataDefinition> requirements = originTopologyTemplate.getRequirements();
1016         if (MapUtils.isNotEmpty(requirements)) {
1017             allReqs = prepareCalculatedRequirementForTopologyTemplate(requirements,
1018                 componentInstance, allCalculatedReq);
1019         } else {
1020             allReqs = new MapListRequirementDataDefinition(allCalculatedReq);
1021         }
1022
1023         if (!allReqs.isEmpty()) {
1024             StorageOperationStatus calculatedRequirementResult =
1025                 addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
1026                     EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS,
1027                     allReqs, componentInstance.getUniqueId());
1028             if (calculatedRequirementResult != StorageOperationStatus.OK) {
1029                 return calculatedRequirementResult;
1030             }
1031             MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
1032             calculatedRequirementResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
1033                 EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS,
1034                 fullCalculatedReq,
1035                 componentInstance.getUniqueId());
1036             if (calculatedRequirementResult != StorageOperationStatus.OK) {
1037                 return calculatedRequirementResult;
1038             }
1039         }
1040         Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
1041         Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
1042
1043         if (calculatedCapabilitiesProperties != null && !calculatedCapabilitiesProperties.isEmpty()) {
1044             for (MapCapabilityProperty map : calculatedCapabilitiesProperties.values()) {
1045                 for (Entry<String, MapPropertiesDataDefinition> entry : map.getMapToscaDataDefinition().entrySet()) {
1046                     String newKey = (componentInstance.getUniqueId() + ModelConverter.CAP_PROP_DELIM + entry.getKey());
1047                     updateKeyMap.put(newKey, entry.getValue());
1048                 }
1049             }
1050         }
1051         Map<String, MapPropertiesDataDefinition> capabilitiesProperties =
1052             originTopologyTemplate.getCapabilitiesProperties();
1053         Map<String, MapPropertiesDataDefinition> updateKeyMapCapabilitiesProperties;
1054         if (MapUtils.isNotEmpty(capabilitiesProperties)) {
1055             updateKeyMapCapabilitiesProperties = capabilitiesProperties.entrySet().stream()
1056                 .collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(),
1057                     componentInstance.getUniqueId()), Entry::getValue));
1058         } else {
1059             updateKeyMapCapabilitiesProperties = new HashMap<>();
1060         }
1061         updateKeyMap.putAll(updateKeyMapCapabilitiesProperties);
1062         MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
1063
1064         if (MapUtils.isNotEmpty(capabilitiesProperties) || MapUtils.isNotEmpty(calculatedCapabilitiesProperties)) {
1065             StorageOperationStatus calculatedResult =
1066                 addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
1067                     EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
1068                     VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabilityProperty,
1069                     componentInstance.getUniqueId());
1070             if (calculatedResult != StorageOperationStatus.OK) {
1071                 return calculatedResult;
1072             }
1073         }
1074         return StorageOperationStatus.OK;
1075     }
1076
1077     public CapabilityDataDefinition updateComponentInstanceCapabilities(final String componentId, final String componentInstanceUniqueId,
1078                                                                         final CapabilityDataDefinition capabilityDataDefinition) {
1079
1080         final GraphVertex containerVertex = findComponentVertex(componentId).orElse(null);
1081         if (containerVertex == null) {
1082             throw new OperationException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1083         }
1084
1085         final Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>> capabilityVertexAndDataPair =
1086             findCapabilityVertex(containerVertex).orElse(null);
1087         if (capabilityVertexAndDataPair == null) {
1088             throw new OperationException(ActionStatus.CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, capabilityDataDefinition.getName(),
1089                 capabilityDataDefinition.getOwnerName(), componentId);
1090         }
1091         final GraphVertex capabilitiesVertex = capabilityVertexAndDataPair.getLeft();
1092         final Map<String, MapListCapabilityDataDefinition> capabilityDataMap = capabilityVertexAndDataPair.getRight();
1093
1094         final CapabilityDataDefinition actualCapabilityDataDefinition =
1095             findCapability(capabilityDataMap, componentInstanceUniqueId, capabilityDataDefinition.getType(), capabilityDataDefinition.getUniqueId())
1096                 .orElse(null);
1097         if (actualCapabilityDataDefinition == null) {
1098             throw new OperationException(ActionStatus.CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, capabilityDataDefinition.getName(),
1099                 capabilityDataDefinition.getOwnerName(), componentId);
1100         }
1101         bindCapabilityDefinition(capabilityDataDefinition, actualCapabilityDataDefinition);
1102
1103         var storageOperationStatus = updateCapabilityVertex(containerVertex, capabilitiesVertex);
1104         if (storageOperationStatus != StorageOperationStatus.OK) {
1105             throw new OperationException(ActionStatus.COMPONENT_INSTANCE_CAPABILITY_UPDATE_ERROR, capabilityDataDefinition.getName());
1106         }
1107         return new CapabilityDataDefinition(actualCapabilityDataDefinition);
1108     }
1109
1110     private void bindCapabilityDefinition(final CapabilityDataDefinition fromCapabilityDefinition,
1111                                           final CapabilityDataDefinition capabilityDefinitionToUpdate) {
1112         capabilityDefinitionToUpdate.setExternal(fromCapabilityDefinition.isExternal());
1113         capabilityDefinitionToUpdate.setExternalName(fromCapabilityDefinition.getExternalName());
1114     }
1115
1116     private Optional<GraphVertex> findComponentVertex(final String componentId) {
1117         final Either<GraphVertex, JanusGraphOperationStatus> componentEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1118         if (componentEither.isRight()) {
1119             final JanusGraphOperationStatus error = componentEither.right().value();
1120             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1121             if (error == JanusGraphOperationStatus.NOT_FOUND) {
1122                 return Optional.empty();
1123             }
1124             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
1125                 FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1126             throw new OperationException(ActionStatus.COMPONENT_FIND_ERROR, componentId);
1127         }
1128         return Optional.ofNullable(componentEither.left().value());
1129     }
1130
1131     private Optional<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>> findCapabilityVertex(final GraphVertex containerVertex) {
1132
1133         final Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capabilitiesEither =
1134             fetchContainerCalculatedCapability(containerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1135         if (capabilitiesEither.isRight()) {
1136             final StorageOperationStatus error = capabilitiesEither.right().value();
1137             if (error == StorageOperationStatus.NOT_FOUND) {
1138                 return Optional.empty();
1139             }
1140             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
1141                 FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, containerVertex.getUniqueId(), error);
1142             throw new OperationException(ActionStatus.COMPONENT_CAPABILITIES_FIND_ERROR, containerVertex.getUniqueId());
1143         }
1144         return Optional.ofNullable(capabilitiesEither.left().value());
1145     }
1146
1147     private Optional<CapabilityDataDefinition> findCapability(final Map<String, MapListCapabilityDataDefinition> capabilityMap,
1148                                                               final String componentInstanceUniqueId,
1149                                                               final String capabilityType,
1150                                                               final String capabilityUniqueId) {
1151         var componentInstanceCapabilitiesMap = capabilityMap.get(componentInstanceUniqueId);
1152         if (componentInstanceCapabilitiesMap == null || componentInstanceCapabilitiesMap.isEmpty()) {
1153             return Optional.empty();
1154         }
1155         var listCapabilityDataDefinition = componentInstanceCapabilitiesMap.getMapToscaDataDefinition().get(capabilityType);
1156         if (listCapabilityDataDefinition == null || listCapabilityDataDefinition.isEmpty()) {
1157             return Optional.empty();
1158         }
1159
1160         return listCapabilityDataDefinition.getListToscaDataDefinition().stream()
1161             .filter(e -> e.getUniqueId().equals(capabilityUniqueId))
1162             .findFirst();
1163     }
1164
1165     public StorageOperationStatus updateComponentInstanceRequirement(String componentId, String componentInstanceUniqueId,
1166                                                                      RequirementDataDefinition requirementDataDefinition) {
1167         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao
1168             .getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1169         if (containerVEither.isRight()) {
1170             JanusGraphOperationStatus error = containerVEither.right().value();
1171             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1172             return StorageOperationStatus.GENERAL_ERROR;
1173         }
1174         GraphVertex containerV = containerVEither.left().value();
1175         return updateComponentInstanceRequirement(componentId, componentInstanceUniqueId, requirementDataDefinition, containerV);
1176     }
1177
1178     private StorageOperationStatus updateComponentInstanceRequirement(String componentId, String componentInstanceUniqueId,
1179                                                                       RequirementDataDefinition requirementDataDefinition, GraphVertex containerV) {
1180         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> existingReqs = getCalculatedRequirements(
1181             componentId);
1182         if (existingReqs.isRight()) {
1183             return existingReqs.right().value();
1184         }
1185         MapListRequirementDataDefinition componentInstanceRequirementsMap = existingReqs.left().value().getRight().get(componentInstanceUniqueId);
1186         if (componentInstanceRequirementsMap == null) {
1187             return StorageOperationStatus.NOT_FOUND;
1188         }
1189         ListRequirementDataDefinition listRequirementDataDefinition = componentInstanceRequirementsMap.getMapToscaDataDefinition()
1190             .get(requirementDataDefinition.getCapability());
1191
1192         listRequirementDataDefinition.getListToscaDataDefinition().stream()
1193             .filter(e -> requirementDataDefinition.getOwnerId().equals(e.getOwnerId()) && requirementDataDefinition.getName().equals(e.getName()))
1194             .forEach(r -> {r.setExternal(requirementDataDefinition.isExternal()); r.setExternalName(requirementDataDefinition.getExternalName());});
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, null);
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 (!ValidationUtils.validateStringNotEmpty(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.buildResourceInstanceUniuqeId(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         return instanceName + " " + (instanceSuffixNumber == null ? 0 : instanceSuffixNumber);
1563     }
1564
1565     public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(Component component, String componentId,
1566                                                                                                   RequirementCapabilityRelDef relation) {
1567         List<RequirementCapabilityRelDef> relations = new ArrayList<>();
1568         relations.add(relation);
1569         Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances = associateResourceInstances(component,
1570             componentId, relations);
1571         if (associateResourceInstances.isRight()) {
1572             return Either.right(associateResourceInstances.right().value());
1573         }
1574         return Either.left(associateResourceInstances.left().value().get(0));
1575     }
1576
1577     @SuppressWarnings({"unchecked"})
1578     public <T extends ToscaDataDefinition> Either<List<RequirementCapabilityRelDef>, StorageOperationStatus> associateResourceInstances(
1579         Component component, String componentId, List<RequirementCapabilityRelDef> relations) {
1580         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1581         if (containerVEither.isRight()) {
1582             JanusGraphOperationStatus error = containerVEither.right().value();
1583             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1584             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1585         }
1586         GraphVertex containerV = containerVEither.left().value();
1587         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(
1588             containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1589         if (capResult.isRight()) {
1590             return Either.right(capResult.right().value());
1591         }
1592         Map<String, MapListCapabilityDataDefinition> calculatedCapabilty = capResult.left().value().getRight();
1593         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(
1594             containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1595         if (capResult.isRight()) {
1596             return Either.right(capResult.right().value());
1597         }
1598         Map<String, MapListCapabilityDataDefinition> fullFilledCapabilty = capFullResult.left().value().getRight();
1599         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(
1600             containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1601         if (reqResult.isRight()) {
1602             return Either.right(reqResult.right().value());
1603         }
1604         Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1605         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(
1606             containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1607         if (reqResult.isRight()) {
1608             return Either.right(reqResult.right().value());
1609         }
1610         Map<String, MapListRequirementDataDefinition> fullfilledRequirement = reqFullResult.left().value().getRight();
1611         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1612         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1613         StorageOperationStatus status;
1614         List<RequirementCapabilityRelDef> relationsList = new ArrayList<>();
1615         for (RequirementCapabilityRelDef relation : relations) {
1616             List<CapabilityRequirementRelationship> relationshipsResult = new ArrayList<>();
1617             String fromNode = relation.getFromNode();
1618             String toNode = relation.getToNode();
1619             List<CapabilityRequirementRelationship> relationships = relation.getRelationships();
1620             if (relationships == null || relationships.isEmpty()) {
1621                 BeEcompErrorManager.getInstance()
1622                     .logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1623                 CommonUtility
1624                     .addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement definition sent in order to set the relation between {} to {}", fromNode,
1625                         toNode);
1626                 loggerSupportability.log(LogLevel.INFO, LoggerSupportabilityActions.CREATE_RELATION.getName(),
1627                     "componentId: " + componentId + " No requirement definition sent in order to set the relation between: " + fromNode + " to: "
1628                         + toNode);
1629                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
1630             }
1631             for (final CapabilityRequirementRelationship relationship : relationships) {
1632                 final String requirement = relationship.getRelation().getRequirement();
1633                 Either<Map<JsonPresentationFields, T>, StorageOperationStatus> associateRes = connectInstancesInContainer(fromNode, toNode,
1634                     relationship.getRelation(), relation.isOriginUI(), calculatedCapabilty, calculatedRequirement, fullFilledCapabilty,
1635                     fullfilledRequirement, compositionDataDefinition, containerV.getUniqueId());
1636                 if (associateRes.isRight()) {
1637                     status = associateRes.right().value();
1638                     BeEcompErrorManager.getInstance()
1639                         .logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId);
1640                     loggerSupportability.log(LogLevel.INFO, LoggerSupportabilityActions.CREATE_RELATIONS.name(), StatusCode.ERROR,
1641                         "missing relationship: " + fromNode, "ComopnentId: " + componentId);
1642                     CommonUtility
1643                         .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate resource instance {} to resource instance {}. status is {}",
1644                             fromNode, toNode, status);
1645                     return Either.right(status);
1646                 }
1647                 final Map<JsonPresentationFields, T> relationshipFieldsMap = associateRes.left().value();
1648                 final RelationshipInstDataDefinition relationshipInstData = (RelationshipInstDataDefinition) relationshipFieldsMap
1649                     .get(JsonPresentationFields.RELATIONSHIP);
1650                 createRelationshipInterfaces(relationship.getOperations()).ifPresent(relationshipInstData::setInterfaces);
1651                 RelationshipImpl relationshipImplResult = new RelationshipImpl();
1652                 relationshipImplResult.setType(relationshipInstData.getType());
1653                 RelationshipInfo requirementAndRelationshipPair = new RelationshipInfo(requirement, relationshipImplResult);
1654                 requirementAndRelationshipPair.setCapability(relationship.getRelation().getCapability());
1655                 requirementAndRelationshipPair.setRequirement(relationship.getRelation().getRequirement());
1656                 requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId());
1657                 requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId());
1658                 requirementAndRelationshipPair.setCapabilityUid(relationship.getRelation().getCapabilityUid());
1659                 requirementAndRelationshipPair.setRequirementUid(relationship.getRelation().getRequirementUid());
1660                 requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
1661                 CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
1662                 capReqRel.setRelation(requirementAndRelationshipPair);
1663                 capReqRel.setCapability((CapabilityDataDefinition) relationshipFieldsMap.get(JsonPresentationFields.CAPABILITY));
1664                 capReqRel.setRequirement((RequirementDataDefinition) relationshipFieldsMap.get(JsonPresentationFields.REQUIREMENT));
1665                 capReqRel.setOperations(relationship.getOperations());
1666                 relationshipsResult.add(capReqRel);
1667                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(),
1668                     relation.getToNode());
1669                 status = updateCustomizationUUID(relation.getFromNode(), compositionDataDefinition);
1670                 if (status != StorageOperationStatus.OK) {
1671                     loggerSupportability.log(LogLevel.INFO, LoggerSupportabilityActions.CREATE_RELATIONS.name(), StatusCode.ERROR,
1672                         "ERROR while update customization UUID for from CI " + relation.getFromNode() + " and to CI: " + relation.getToNode());
1673                     return Either.right(status);
1674                 }
1675                 status = updateCustomizationUUID(relation.getToNode(), compositionDataDefinition);
1676                 if (status != StorageOperationStatus.OK) {
1677                     loggerSupportability.log(LogLevel.INFO, LoggerSupportabilityActions.CREATE_RELATIONS.name(), StatusCode.ERROR,
1678                         "ERROR while update customization UUID for from CI " + relation.getFromNode() + " and to CI: " + relation.getToNode());
1679                     return Either.right(status);
1680                 }
1681             }
1682             RequirementCapabilityRelDef reqCapRelDef = new RequirementCapabilityRelDef(relation);
1683             reqCapRelDef.setRelationships(relationshipsResult);
1684             relationsList.add(reqCapRelDef);
1685         }
1686         status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1687         if (status != StorageOperationStatus.OK) {
1688             return Either.right(status);
1689         }
1690         return Either.left(relationsList);
1691     }
1692
1693     private Optional<ListDataDefinition<InterfaceDataDefinition>> createRelationshipInterfaces(final List<OperationUi> operationList) {
1694         if (CollectionUtils.isEmpty(operationList)) {
1695             return Optional.empty();
1696         }
1697         final ListDataDefinition<InterfaceDataDefinition> interfaceList = new ListDataDefinition<>();
1698         final Map<String, List<OperationUi>> operationByInterfaceType = operationList.stream()
1699             .collect(Collectors.groupingBy(OperationUi::getInterfaceType));
1700         for (final Entry<String, List<OperationUi>> interfaceEntry : operationByInterfaceType.entrySet()) {
1701             interfaceList.add(createInterface(interfaceEntry.getKey(), interfaceEntry.getValue()));
1702         }
1703         return Optional.of(interfaceList);
1704     }
1705
1706     private InterfaceDataDefinition createInterface(final String interfaceType, final List<OperationUi> operationList) {
1707         final InterfaceDataDefinition interfaceDataDefinition = new InterfaceDataDefinition();
1708         interfaceDataDefinition.setType(interfaceType);
1709         if (CollectionUtils.isNotEmpty(operationList)) {
1710             final Map<String, OperationDataDefinition> operationMap = operationList.stream()
1711                 .collect(Collectors.toMap(OperationUi::getOperationType, this::createOperation));
1712             interfaceDataDefinition.setOperations(operationMap);
1713         }
1714         return interfaceDataDefinition;
1715     }
1716
1717     private OperationDataDefinition createOperation(final OperationUi operation) {
1718         final OperationDataDefinition operationDataDefinition = new OperationDataDefinition();
1719         operationDataDefinition.setName(operation.getOperationType());
1720         operationDataDefinition.setUniqueId(UUID.randomUUID().toString());
1721         final ArtifactDataDefinition implementation = new ArtifactDataDefinition();
1722         implementation.setArtifactName(operation.getImplementation());
1723         operationDataDefinition.setImplementation(implementation);
1724         if (CollectionUtils.isNotEmpty(operation.getInputs())) {
1725             final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
1726             operation.getInputs().forEach(input -> {
1727                 final OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
1728                 operationInputDefinition.setLabel(input.getName());
1729                 operationInputDefinition.setType(input.getType());
1730                 operationInputDefinition.setValue(input.getValue());
1731                 inputs.add(operationInputDefinition);
1732             });
1733             operationDataDefinition.setInputs(inputs);
1734         }
1735         return operationDataDefinition;
1736     }
1737
1738     private StorageOperationStatus updateAllAndCalculatedCapReqOnGraph(String componentId, GraphVertex containerV,
1739                                                                        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult,
1740                                                                        Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult,
1741                                                                        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult,
1742                                                                        Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult) {
1743         containerV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1744         Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(containerV);
1745         if (updateElement.isRight()) {
1746             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new relations error {}. ", componentId,
1747                 updateElement.right().value());
1748             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value());
1749         }
1750         // update cap/req jsons, fulfilled cap/req jsons!!!!!
1751         Either<GraphVertex, JanusGraphOperationStatus> status;
1752         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated capabilty for container {}", containerV.getUniqueId());
1753         status = updateOrCopyOnUpdate(capResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1754         if (status.isRight()) {
1755             JanusGraphOperationStatus error = status.right().value();
1756             CommonUtility
1757                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated capabilty for container {} error {}", containerV.getUniqueId(),
1758                     error);
1759             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1760         }
1761         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update calculated requirement for container {}", containerV.getUniqueId());
1762         status = updateOrCopyOnUpdate(reqResult.left().value().getLeft(), containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1763         if (status.isRight()) {
1764             JanusGraphOperationStatus error = status.right().value();
1765             CommonUtility
1766                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update calculated requiremnt for container {} error {}", containerV.getUniqueId(),
1767                     error);
1768             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1769         }
1770         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled capabilty for container {}", containerV.getUniqueId());
1771         status = updateOrCopyOnUpdate(capFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1772         if (status.isRight()) {
1773             JanusGraphOperationStatus error = status.right().value();
1774             CommonUtility
1775                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled capabilty for container {} error {}", containerV.getUniqueId(),
1776                     error);
1777             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1778         }
1779         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Update fullfilled requirement for container {}", containerV.getUniqueId());
1780         status = updateOrCopyOnUpdate(reqFullResult.left().value().getLeft(), containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1781         if (status.isRight()) {
1782             JanusGraphOperationStatus error = status.right().value();
1783             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update fullfilled requirement for container {} error {}",
1784                 containerV.getUniqueId(), error);
1785             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
1786         }
1787         return StorageOperationStatus.OK;
1788     }
1789
1790     @SuppressWarnings({"unchecked"})
1791     public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId,
1792                                                                                                    RequirementCapabilityRelDef requirementDef) {
1793         if (requirementDef.getRelationships() == null) {
1794             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation pair in request [ {} ]", requirementDef);
1795             return Either.right(StorageOperationStatus.BAD_REQUEST);
1796         }
1797         String fromResInstanceUid = requirementDef.getFromNode();
1798         String toResInstanceUid = requirementDef.getToNode();
1799         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1800         if (containerVEither.isRight()) {
1801             JanusGraphOperationStatus error = containerVEither.right().value();
1802             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1803             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1804         }
1805         GraphVertex containerV = containerVEither.left().value();
1806         // DE191707 - validations
1807         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) containerV.getJson();
1808         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1809         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
1810         ComponentInstanceDataDefinition ciFrom = componentInstances.get(fromResInstanceUid);
1811         if (ciFrom == null) {
1812             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "FROM instance {} isn't under container {}", fromResInstanceUid, componentId);
1813             return Either.right(StorageOperationStatus.NOT_FOUND);
1814         }
1815         ComponentInstanceDataDefinition ciTo = componentInstances.get(toResInstanceUid);
1816         if (ciFrom == ciTo) {
1817             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "TO instance {} isn't under container {}", toResInstanceUid, componentId);
1818             return Either.right(StorageOperationStatus.NOT_FOUND);
1819         }
1820         Map<String, RelationshipInstDataDefinition> relations = compositionDataDefinition.getRelations();
1821         List<CapabilityRequirementRelationship> relationPairList = requirementDef.getRelationships();
1822         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capResult = fetchContainerCalculatedCapability(
1823             containerV, EdgeLabelEnum.CALCULATED_CAPABILITIES);
1824         if (capResult.isRight()) {
1825             return Either.right(capResult.right().value());
1826         }
1827         Map<String, MapListCapabilityDataDefinition> calculatedCapability = capResult.left().value().getRight();
1828         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = fetchContainerCalculatedCapability(
1829             containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1830         if (capResult.isRight()) {
1831             return Either.right(capResult.right().value());
1832         }
1833         Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1834         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqResult = fetchContainerCalculatedRequirement(
1835             containerV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
1836         if (reqResult.isRight()) {
1837             return Either.right(reqResult.right().value());
1838         }
1839         Map<String, MapListRequirementDataDefinition> calculatedRequirement = reqResult.left().value().getRight();
1840         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = fetchContainerCalculatedRequirement(
1841             containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1842         if (reqResult.isRight()) {
1843             return Either.right(reqResult.right().value());
1844         }
1845         Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1846         for (CapabilityRequirementRelationship relationPair : relationPairList) {
1847             Iterator<Entry<String, RelationshipInstDataDefinition>> iterator = relations.entrySet().iterator();
1848             boolean isDeleted = false;
1849             while (iterator.hasNext()) {
1850                 Entry<String, RelationshipInstDataDefinition> entryInJson = iterator.next();
1851                 RelationshipInstDataDefinition relationInJson = entryInJson.getValue();
1852                 if (relationInJson.getFromId().equals(fromResInstanceUid) && relationInJson.getToId().equals(toResInstanceUid) && relationInJson
1853                     .getUniqueId().equals(relationPair.getRelation().getId())) {
1854                     if (relationPair.getRelation().equalsTo(relationInJson)) {
1855                         CommonUtility
1856                             .addRecordToLog(log, LogLevelEnum.DEBUG, "Remove relation from {} to {} capability {} capOwnerId {} reqOwnerId {} ",
1857                                 toResInstanceUid, componentId, relationInJson.getType(), relationInJson.getCapabilityOwnerId(),
1858                                 relationInJson.getRequirementOwnerId());
1859                         iterator.remove();
1860                         // update calculated cap/req
1861                         StorageOperationStatus status = updateCalculatedCapabiltyAfterDeleteRelation(calculatedCapability, fulfilledCapability,
1862                             toResInstanceUid, relationInJson, relationPair);
1863                         if (status != StorageOperationStatus.OK) {
1864                             return Either.right(status);
1865                         }
1866                         status = updateCalculatedRequirementsAfterDeleteRelation(calculatedRequirement, fulfilledRequirement, fromResInstanceUid,
1867                             relationInJson, relationPair);
1868                         if (status != StorageOperationStatus.OK) {
1869                             return Either.right(status);
1870                         }
1871                         isDeleted = true;
1872                     }
1873                 }
1874             }
1875             if (!isDeleted) {
1876                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No relation to delete from {} to {} capabilty {} capOwnerId {} reqOwnerId {} ",
1877                     toResInstanceUid, componentId, relationPair.getCapability(), relationPair.getRelation().getCapabilityOwnerId(),
1878                     relationPair.getRelation().getRequirementOwnerId());
1879                 return Either.right(StorageOperationStatus.NOT_FOUND);
1880             }
1881         }
1882         StorageOperationStatus status = updateCustomizationUUID(fromResInstanceUid, compositionDataDefinition);
1883         if (status != StorageOperationStatus.OK) {
1884             return Either.right(status);
1885         }
1886         status = updateCustomizationUUID(toResInstanceUid, compositionDataDefinition);
1887         if (status != StorageOperationStatus.OK) {
1888             return Either.right(status);
1889         }
1890         // update jsons
1891
1892         // update metadata of container and composition json
1893         status = updateAllAndCalculatedCapReqOnGraph(componentId, containerV, capResult, capFullResult, reqResult, reqFullResult);
1894         if (status != StorageOperationStatus.OK) {
1895             return Either.right(status);
1896         }
1897         return Either.left(requirementDef);
1898     }
1899
1900     /**
1901      * Retrieves fulfilled requirement according to relation and received predicate
1902      *
1903      * @param componentId
1904      * @param instanceId
1905      * @param foundRelation
1906      * @param predicate
1907      * @return
1908      */
1909     public Either<RequirementDataDefinition, StorageOperationStatus> getFulfilledRequirementByRelation(String componentId, String instanceId,
1910                                                                                                        RequirementCapabilityRelDef foundRelation,
1911                                                                                                        BiPredicate<RelationshipInfo, RequirementDataDefinition> predicate) {
1912         Either<RequirementDataDefinition, StorageOperationStatus> result = null;
1913         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> reqFullResult = null;
1914         MapListRequirementDataDefinition reqMapOfLists = null;
1915         Optional<RequirementDataDefinition> foundRequirement;
1916         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1917         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1918         if (containerVEither.isRight()) {
1919             JanusGraphOperationStatus error = containerVEither.right().value();
1920             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1921             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1922         }
1923         if (result == null) {
1924             GraphVertex containerV = containerVEither.left().value();
1925             reqFullResult = fetchContainerCalculatedRequirement(containerV, EdgeLabelEnum.FULLFILLED_REQUIREMENTS);
1926             if (reqFullResult.isRight()) {
1927                 result = Either.right(reqFullResult.right().value());
1928             }
1929         }
1930         if (result == null) {
1931             Map<String, MapListRequirementDataDefinition> fulfilledRequirement = reqFullResult.left().value().getRight();
1932             reqMapOfLists = fulfilledRequirement.get(instanceId);
1933             if (reqMapOfLists == null) {
1934                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1935             }
1936         }
1937         if (result == null && reqMapOfLists != null) {
1938             for (ListRequirementDataDefinition requirements : reqMapOfLists.getMapToscaDataDefinition().values()) {
1939                 foundRequirement = requirements.getListToscaDataDefinition().stream().filter(req -> predicate.test(relationshipInfo, req))
1940                     .findFirst();
1941                 if (foundRequirement.isPresent()) {
1942                     result = Either.left(foundRequirement.get());
1943                 }
1944             }
1945         }
1946         return result;
1947     }
1948
1949     /**
1950      * Retrieves fulfilled capability according to relation and received predicate
1951      *
1952      * @param componentId
1953      * @param instanceId
1954      * @param foundRelation
1955      * @param predicate
1956      * @return
1957      */
1958     public Either<CapabilityDataDefinition, StorageOperationStatus> getFulfilledCapabilityByRelation(String componentId, String instanceId,
1959                                                                                                      RequirementCapabilityRelDef foundRelation,
1960                                                                                                      BiPredicate<RelationshipInfo, CapabilityDataDefinition> predicate) {
1961         Either<CapabilityDataDefinition, StorageOperationStatus> result = null;
1962         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> capFullResult = null;
1963         MapListCapabilityDataDefinition capMapOfLists = null;
1964         Optional<CapabilityDataDefinition> foundRequirement;
1965         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1966         Either<GraphVertex, JanusGraphOperationStatus> containerVEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
1967         if (containerVEither.isRight()) {
1968             JanusGraphOperationStatus error = containerVEither.right().value();
1969             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FETCH_CONTAINER_VERTEX_ERROR, componentId, error);
1970             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
1971         }
1972         if (result == null) {
1973             GraphVertex containerV = containerVEither.left().value();
1974             capFullResult = fetchContainerCalculatedCapability(containerV, EdgeLabelEnum.FULLFILLED_CAPABILITIES);
1975             if (capFullResult.isRight()) {
1976                 result = Either.right(capFullResult.right().value());
1977             }
1978         }
1979         if (result == null) {
1980             Map<String, MapListCapabilityDataDefinition> fulfilledCapability = capFullResult.left().value().getRight();
1981             capMapOfLists = fulfilledCapability.get(instanceId);
1982             if (capMapOfLists == null) {
1983                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1984             }
1985         }
1986         if (result == null && capMapOfLists != null) {
1987             for (ListCapabilityDataDefinition capabilities : capMapOfLists.getMapToscaDataDefinition().values()) {
1988                 foundRequirement = capabilities.getListToscaDataDefinition().stream().filter(cap -> predicate.test(relationshipInfo, cap))
1989                     .findFirst();
1990                 if (foundRequirement.isPresent()) {
1991                     result = Either.left(foundRequirement.get());
1992                 }
1993             }
1994         }
1995         return result;
1996     }
1997
1998     private StorageOperationStatus updateCalculatedRequirementsAfterDeleteRelation(
1999         Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListRequirementDataDefinition> fullFilledRequirement,
2000         String fromResInstanceUid, RelationshipInstDataDefinition relation, CapabilityRequirementRelationship relationship) {
2001         StorageOperationStatus status;
2002         String hereIsTheKey = null;
2003         MapListRequirementDataDefinition reqByInstance = calculatedRequirement.get(fromResInstanceUid);
2004         if (reqByInstance == null || reqByInstance.findKeyByItemUidMatch(relation.getRequirementId()) == null) {
2005             // move from fulfilled
2006             status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey,
2007                 relationship);
2008         } else {
2009             hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
2010             ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
2011             Optional<RequirementDataDefinition> requirementOptional = reqByType.getListToscaDataDefinition().stream().filter(
2012                 req -> req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req
2013                     .getUniqueId().equals(relation.getRequirementId())).findFirst();
2014             if (requirementOptional.isPresent()) {
2015                 RequirementDataDefinition requirement = requirementOptional.get();
2016                 String leftOccurrences = requirement.getLeftOccurrences();
2017                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
2018                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
2019                     ++leftIntValue;
2020                     requirement.setLeftOccurrences(String.valueOf(leftIntValue));
2021                 }
2022                 if (relationship != null) {
2023                     relationship.setRequirement(requirement);
2024                 }
2025                 status = StorageOperationStatus.OK;
2026             } else {
2027                 // move from fulfilled
2028                 status = moveFromFullFilledRequirement(calculatedRequirement, fullFilledRequirement, fromResInstanceUid, relation, hereIsTheKey,
2029                     relationship);
2030             }
2031         }
2032         return status;
2033     }
2034
2035     private StorageOperationStatus updateCalculatedCapabiltyAfterDeleteRelation(Map<String, MapListCapabilityDataDefinition> calculatedCapability,
2036                                                                                 Map<String, MapListCapabilityDataDefinition> fullFilledCapability,
2037                                                                                 String toResInstanceUid, RelationshipInstDataDefinition relation,
2038                                                                                 CapabilityRequirementRelationship relationship) {
2039         StorageOperationStatus status;
2040         String hereIsTheKey = null;
2041         MapListCapabilityDataDefinition capByInstance = calculatedCapability.get(toResInstanceUid);
2042         if (capByInstance == null || capByInstance.findKeyByItemUidMatch(relation.getCapabilityId()) == null) {
2043             // move from fulfilled
2044             status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey, relationship);
2045         } else {
2046             hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
2047             ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
2048             Optional<CapabilityDataDefinition> capabilityOptional = capByType.getListToscaDataDefinition().stream()
2049                 .filter(cap -> cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId()))
2050                 .findFirst();
2051             if (capabilityOptional.isPresent()) {
2052                 CapabilityDataDefinition capability = capabilityOptional.get();
2053                 String leftOccurrences = capability.getLeftOccurrences();
2054                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
2055                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
2056                     ++leftIntValue;
2057                     capability.setLeftOccurrences(String.valueOf(leftIntValue));
2058                 }
2059                 if (relationship != null) {
2060                     relationship.setCapability(capability);
2061                 }
2062                 status = StorageOperationStatus.OK;
2063             } else {
2064                 // move from fulfilled
2065                 status = moveFromFullFilledCapabilty(calculatedCapability, fullFilledCapability, toResInstanceUid, relation, hereIsTheKey,
2066                     relationship);
2067             }
2068         }
2069         return status;
2070     }
2071
2072     private StorageOperationStatus moveFromFullFilledCapabilty(Map<String, MapListCapabilityDataDefinition> calculatedCapability,
2073                                                                Map<String, MapListCapabilityDataDefinition> fullFilledCapability,
2074                                                                String toResInstanceUid, RelationshipInstDataDefinition relation, String hereIsTheKey,
2075                                                                CapabilityRequirementRelationship relationship) {
2076         MapListCapabilityDataDefinition capByInstance = fullFilledCapability.get(toResInstanceUid);
2077         if (capByInstance == null) {
2078             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No capability in fulfilled list for instance {} ", toResInstanceUid);
2079             return StorageOperationStatus.GENERAL_ERROR;
2080         }
2081         if (null == hereIsTheKey) {
2082             hereIsTheKey = capByInstance.findKeyByItemUidMatch(relation.getCapabilityId());
2083         }
2084         if (null == hereIsTheKey) {
2085             CommonUtility
2086                 .addRecordToLog(log, LogLevelEnum.DEBUG, "No capability with id {} in fulfilled list for instance {} ", relation.getCapabilityId(),
2087                     toResInstanceUid);
2088             return StorageOperationStatus.GENERAL_ERROR;
2089         }
2090         ListCapabilityDataDefinition capByType = capByInstance.findByKey(hereIsTheKey);
2091         Iterator<CapabilityDataDefinition> iterator = capByType.getListToscaDataDefinition().iterator();
2092         boolean found = false;
2093         while (iterator.hasNext()) {
2094             CapabilityDataDefinition cap = iterator.next();
2095             if (cap.getOwnerId().equals(relation.getCapabilityOwnerId()) && cap.getUniqueId().equals(relation.getCapabilityId())) {
2096                 found = true;
2097                 iterator.remove();
2098                 // return to calculated list
2099                 String leftOccurrences = cap.getLeftOccurrences();
2100                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
2101                 ++leftIntValue;
2102                 cap.setLeftOccurrences(String.valueOf(leftIntValue));
2103                 MapListCapabilityDataDefinition mapListCapaDataDef = calculatedCapability.get(toResInstanceUid);
2104                 if (mapListCapaDataDef == null) {
2105                     mapListCapaDataDef = new MapListCapabilityDataDefinition();
2106                 }
2107                 ListCapabilityDataDefinition findByKey = mapListCapaDataDef.findByKey(hereIsTheKey);
2108                 if (findByKey == null) {
2109                     findByKey = new ListCapabilityDataDefinition();
2110                     mapListCapaDataDef.put(hereIsTheKey, findByKey);
2111                 }
2112                 findByKey.add(cap);
2113                 if (relationship != null) {
2114                     relationship.setCapability(cap);
2115                 }
2116                 break;
2117             }
2118         }
2119         if (!found) {
2120             CommonUtility
2121                 .addRecordToLog(log, LogLevelEnum.DEBUG, "No capability type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey,
2122                     relation.getCapabilityOwnerId(), toResInstanceUid);
2123             return StorageOperationStatus.GENERAL_ERROR;
2124         }
2125         return StorageOperationStatus.OK;
2126     }
2127
2128     private StorageOperationStatus moveFromFullFilledRequirement(Map<String, MapListRequirementDataDefinition> calculatedRequirement,
2129                                                                  Map<String, MapListRequirementDataDefinition> fullFilledRequirement,
2130                                                                  String fromResInstanceUid, RelationshipInstDataDefinition relation,
2131                                                                  String hereIsTheKey, CapabilityRequirementRelationship relationship) {
2132         MapListRequirementDataDefinition reqByInstance = fullFilledRequirement.get(fromResInstanceUid);
2133         if (reqByInstance == null) {
2134             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement in fullfilled list for instance {} ", fromResInstanceUid);
2135             return StorageOperationStatus.GENERAL_ERROR;
2136         }
2137         if (null == hereIsTheKey) {
2138             hereIsTheKey = reqByInstance.findKeyByItemUidMatch(relation.getRequirementId());
2139         }
2140         if (null == hereIsTheKey) {
2141             CommonUtility
2142                 .addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement with id {} in fulfilled list for instance {} ", relation.getRequirementId(),
2143                     fromResInstanceUid);
2144             return StorageOperationStatus.GENERAL_ERROR;
2145         }
2146         ListRequirementDataDefinition reqByType = reqByInstance.findByKey(hereIsTheKey);
2147         Iterator<RequirementDataDefinition> iterator = reqByType.getListToscaDataDefinition().iterator();
2148         boolean found = false;
2149         while (iterator.hasNext()) {
2150             RequirementDataDefinition req = iterator.next();
2151             if (req.getOwnerId().equals(relation.getRequirementOwnerId()) && req.getName().equals(relation.getRequirement()) && req.getUniqueId()
2152                 .equals(relation.getRequirementId())) {
2153                 found = true;
2154                 iterator.remove();
2155                 // return to calculated list
2156                 String leftOccurrences = req.getLeftOccurrences();
2157                 Integer leftIntValue = Integer.parseInt(leftOccurrences);
2158                 ++leftIntValue;
2159                 req.setLeftOccurrences(String.valueOf(leftIntValue));
2160                 MapListRequirementDataDefinition mapListReqDataDef = calculatedRequirement.get(fromResInstanceUid);
2161                 if (mapListReqDataDef == null) {
2162                     mapListReqDataDef = new MapListRequirementDataDefinition();
2163                 }
2164                 ListRequirementDataDefinition findByKey = mapListReqDataDef.findByKey(hereIsTheKey);
2165                 if (findByKey == null) {
2166                     findByKey = new ListRequirementDataDefinition();
2167                     mapListReqDataDef.put(hereIsTheKey, findByKey);
2168                 }
2169                 findByKey.add(req);
2170                 if (relationship != null) {
2171                     relationship.setRequirement(req);
2172                 }
2173                 break;
2174             }
2175         }
2176         if (!found) {
2177             CommonUtility
2178                 .addRecordToLog(log, LogLevelEnum.DEBUG, "No requirement type {} with ownerId {} in fulfilled list for instance {} ", hereIsTheKey,
2179                     relation.getRequirementOwnerId(), fromResInstanceUid);
2180             return StorageOperationStatus.GENERAL_ERROR;
2181         }
2182         return StorageOperationStatus.OK;
2183     }
2184
2185     public StorageOperationStatus updateCustomizationUUID(String componentInstanceId, CompositionDataDefinition compositionDataDefinition) {
2186         ComponentInstanceDataDefinition componentInstance = compositionDataDefinition.getComponentInstances().get(componentInstanceId);
2187         if (componentInstance == null) {
2188             CommonUtility
2189                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component instance by id {} from map of instances ", componentInstanceId);
2190             return StorageOperationStatus.NOT_FOUND;
2191         }
2192         UUID uuid = UUID.randomUUID();
2193         componentInstance.setCustomizationUUID(uuid.toString());
2194         return StorageOperationStatus.OK;
2195     }
2196
2197     public <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectInstancesInContainer(
2198         String fromResInstanceUid, String toResInstanceUid, RelationshipInfo relationPair, boolean originUI,
2199         Map<String, MapListCapabilityDataDefinition> calculatedCapabilty, Map<String, MapListRequirementDataDefinition> calculatedRequirement,
2200         Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty, Map<String, MapListRequirementDataDefinition> fullfilledRequirement,
2201         CompositionDataDefinition compositionDataDefinition, String containerId) {
2202         String requirement = relationPair.getRequirement();
2203         Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
2204         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
2205             "Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid,
2206             toResInstanceUid, containerId, requirement);
2207         ComponentInstanceDataDefinition fromResourceInstData = componentInstances.get(fromResInstanceUid);
2208         if (fromResourceInstData == null) {
2209             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find from resource instance {}.", fromResInstanceUid);
2210             return Either.right(StorageOperationStatus.NOT_FOUND);
2211         }
2212         ComponentInstanceDataDefinition toResourceInstData = componentInstances.get(toResInstanceUid);
2213         if (toResourceInstData == null) {
2214             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find to resource instance {}.", toResInstanceUid);
2215             return Either.right(StorageOperationStatus.NOT_FOUND);
2216         }
2217         Either<Map<JsonPresentationFields, T>, StorageOperationStatus> reqVsCap = connectRequirementVsCapability(fromResourceInstData,
2218             toResourceInstData, relationPair, originUI, calculatedCapabilty, calculatedRequirement, fullfilledCapabilty, fullfilledRequirement,
2219             containerId);
2220         if (reqVsCap.isRight()) {
2221             StorageOperationStatus status = reqVsCap.right().value();
2222             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
2223                 "Failed to connect requirement {} between resource instance {} to resource instance {}. status is {}", requirement,
2224                 fromResInstanceUid, toResInstanceUid, status);
2225             return Either.right(status);
2226         }
2227         Map<JsonPresentationFields, T> relationship = reqVsCap.left().value();
2228         // add to json new relations
2229         compositionDataDefinition.addRelation(((RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP)).getUniqueId(),
2230             (RelationshipInstDataDefinition) relationship.get(JsonPresentationFields.RELATIONSHIP));
2231         return Either.left(relationship);
2232     }
2233
2234     private Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedCapability(
2235         GraphVertex containerV, EdgeLabelEnum capLabel) {
2236         Either<Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>>, JanusGraphOperationStatus> calculatedCapabiltyEither = getDataAndVertexFromGraph(
2237             containerV, capLabel);
2238         if (calculatedCapabiltyEither.isRight()) {
2239             JanusGraphOperationStatus error = calculatedCapabiltyEither.right().value();
2240             CommonUtility
2241                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilties for container {}.", containerV.getUniqueId(), error);
2242             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
2243         }
2244         Pair<GraphVertex, Map<String, MapListCapabilityDataDefinition>> calculatedCapabilty = calculatedCapabiltyEither.left().value();
2245         return Either.left(calculatedCapabilty);
2246     }
2247
2248     private Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, StorageOperationStatus> fetchContainerCalculatedRequirement(
2249         GraphVertex containerV, EdgeLabelEnum reqLabel) {
2250         Either<Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>>, JanusGraphOperationStatus> calculatedRequirementEither = getDataAndVertexFromGraph(
2251             containerV, reqLabel);
2252         if (calculatedRequirementEither.isRight()) {
2253             JanusGraphOperationStatus error = calculatedRequirementEither.right().value();
2254             CommonUtility
2255                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for container {}.", containerV.getUniqueId(),
2256                     error);
2257             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error));
2258         }
2259         Pair<GraphVertex, Map<String, MapListRequirementDataDefinition>> calculatedRequirement = calculatedRequirementEither.left().value();
2260         return Either.left(calculatedRequirement);
2261     }
2262
2263     @SuppressWarnings("unchecked")
2264     private <T extends ToscaDataDefinition> Either<Map<JsonPresentationFields, T>, StorageOperationStatus> connectRequirementVsCapability(
2265         ComponentInstanceDataDefinition fromResInstance, ComponentInstanceDataDefinition toResInstance, RelationshipInfo relationPair,
2266         boolean originUI, Map<String, MapListCapabilityDataDefinition> calculatedCapabilty,
2267         Map<String, MapListRequirementDataDefinition> calculatedRequirement, Map<String, MapListCapabilityDataDefinition> fullfilledCapabilty,
2268         Map<String, MapListRequirementDataDefinition> fullfilledRequirement, String containerId) {
2269         String type = relationPair.getRelationship().getType();
2270         // capability
2271         String toInstId = toResInstance.getUniqueId();
2272         MapListCapabilityDataDefinition mapListCapabilityDataDefinition = calculatedCapabilty.get(toInstId);
2273         Map<JsonPresentationFields, T> capReqRelationship = new EnumMap<>(JsonPresentationFields.class);
2274         if (mapListCapabilityDataDefinition == null) {
2275             CommonUtility
2276                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for instance {} in container {}.", toInstId,
2277                     containerId);
2278             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2279         }
2280         ListCapabilityDataDefinition listCapabilityDataDefinition = mapListCapabilityDataDefinition.getMapToscaDataDefinition().get(type);
2281         if (listCapabilityDataDefinition == null) {
2282             CommonUtility
2283                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated capabilities for type {} for instance {} in container {}.", type,
2284                     toInstId, containerId);
2285             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2286         }
2287         CapabilityDataDefinition capabilityForRelation = null;
2288         Iterator<CapabilityDataDefinition> iteratorCap = listCapabilityDataDefinition.getListToscaDataDefinition().iterator();
2289         while (iteratorCap.hasNext()) {
2290             CapabilityDataDefinition cap = iteratorCap.next();
2291             if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
2292                 capabilityForRelation = cap;
2293                 capReqRelationship.put(JsonPresentationFields.CAPABILITY, (T) capabilityForRelation);
2294                 String leftOccurrences = cap.getLeftOccurrences();
2295                 if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
2296                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
2297                     if (leftIntValue > 0) {
2298                         --leftIntValue;
2299                         capabilityForRelation.setLeftOccurrences(String.valueOf(leftIntValue));
2300                         if (leftIntValue == 0) {
2301                             // remove from calculated
2302                             iteratorCap.remove();
2303                             // move to fulfilled
2304                             MapListCapabilityDataDefinition mapListCapabiltyFullFilledInst = fullfilledCapabilty.get(toInstId);
2305                             if (mapListCapabiltyFullFilledInst == null) {
2306                                 mapListCapabiltyFullFilledInst = new MapListCapabilityDataDefinition();
2307                                 fullfilledCapabilty.put(toInstId, mapListCapabiltyFullFilledInst);
2308                             }
2309                             ListCapabilityDataDefinition listCapabilityFull = mapListCapabiltyFullFilledInst.findByKey(type);
2310                             if (listCapabilityFull == null) {
2311                                 listCapabilityFull = new ListCapabilityDataDefinition();
2312                                 mapListCapabiltyFullFilledInst.put(type, listCapabilityFull);
2313                             }
2314                             listCapabilityFull.add(capabilityForRelation);
2315                         }
2316                         break;
2317                     } else {
2318                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences capabilty {} to {} in container {}.",
2319                             capabilityForRelation.getType(), toInstId, containerId);
2320                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2321                     }
2322                 }
2323             }
2324         }
2325         if (capabilityForRelation == null) {
2326             CommonUtility
2327                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch capabilty for type {} for instance {} in container {}.", type, toInstId,
2328                     containerId);
2329             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2330         }
2331         // requirements
2332         String fromInstId = fromResInstance.getUniqueId();
2333         MapListRequirementDataDefinition mapListRequirementDataDefinition = calculatedRequirement.get(fromInstId);
2334         if (mapListRequirementDataDefinition == null) {
2335             CommonUtility
2336                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for instance {} in container {}.", fromInstId,
2337                     containerId);
2338             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2339         }
2340         ListRequirementDataDefinition listRequirementDataDefinition = mapListRequirementDataDefinition.getMapToscaDataDefinition().get(type);
2341         if (listRequirementDataDefinition == null) {
2342             CommonUtility
2343                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch calculated requirements for type {} for instance {} in container {}.", type,
2344                     fromInstId, containerId);
2345             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2346         }
2347         RequirementDataDefinition requirementForRelation = null;
2348         Iterator<RequirementDataDefinition> iteratorReq = listRequirementDataDefinition.getListToscaDataDefinition().iterator();
2349         while (iteratorReq.hasNext()) {
2350             RequirementDataDefinition req = iteratorReq.next();
2351             if (req.getUniqueId().equals(relationPair.getRequirementUid()) && req.getOwnerId().equals(relationPair.getRequirementOwnerId())) {
2352                 requirementForRelation = req;
2353                 capReqRelationship.put(JsonPresentationFields.REQUIREMENT, (T) requirementForRelation);
2354                 String leftOccurrences = req.getLeftOccurrences();
2355                 if (leftOccurrences != null && !leftOccurrences.equals(RequirementDataDefinition.MAX_OCCURRENCES)) {
2356                     Integer leftIntValue = Integer.parseInt(leftOccurrences);
2357                     if (leftIntValue > 0) {
2358                         --leftIntValue;
2359                         req.setLeftOccurrences(String.valueOf(leftIntValue));
2360                         if (leftIntValue == 0) {
2361                             // remove from calculated
2362                             iteratorReq.remove();
2363                             // move to fulfilled
2364                             MapListRequirementDataDefinition mapListRequirementFullFilledInst = fullfilledRequirement.get(fromInstId);
2365                             if (mapListRequirementFullFilledInst == null) {
2366                                 mapListRequirementFullFilledInst = new MapListRequirementDataDefinition();
2367                                 fullfilledRequirement.put(fromInstId, mapListRequirementFullFilledInst);
2368                             }
2369                             ListRequirementDataDefinition listRequirementFull = mapListRequirementFullFilledInst.findByKey(type);
2370                             if (listRequirementFull == null) {
2371                                 listRequirementFull = new ListRequirementDataDefinition();
2372                                 mapListRequirementFullFilledInst.put(type, listRequirementFull);
2373                             }
2374                             listRequirementFull.add(requirementForRelation);
2375                         }
2376                         break;
2377                     } else {
2378                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "No left occurrences requirement {} from {} to {} in container {}.",
2379                             requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
2380                         return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2381                     }
2382                 }
2383             }
2384         }
2385         if (requirementForRelation == null) {
2386             CommonUtility
2387                 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch requirement for type {} for instance {} in container {}.", type, toInstId,
2388                     containerId);
2389             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2390         }
2391         if (!capabilityForRelation.getType().equals(requirementForRelation.getCapability())) {
2392             CommonUtility
2393                 .addRecordToLog(log, LogLevelEnum.DEBUG, "No macth for capability from type {} and requirement {} from {} to {} in container {}.",
2394                     capabilityForRelation.getType(), requirementForRelation.getCapability(), fromInstId, toInstId, containerId);
2395             return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
2396         }
2397         RelationshipInstDataDefinition relationshipTypeData = buildRelationshipInstData(fromInstId, toInstId, relationPair, originUI);
2398         if (requirementForRelation.getRelationship() != null) {
2399             relationshipTypeData.setType(requirementForRelation.getRelationship());
2400         }
2401         capReqRelationship.put(JsonPresentationFields.RELATIONSHIP, (T) relationshipTypeData);
2402         return Either.left(capReqRelationship);
2403     }
2404
2405     private RelationshipInstDataDefinition buildRelationshipInstData(String fromResInstanceUid, String toInstId, RelationshipInfo relationPair,
2406                                                                      boolean originUI) {
2407         RelationshipInstDataDefinition relationshipInstData = new RelationshipInstDataDefinition();
2408         relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, toInstId));
2409         relationshipInstData.setType(relationPair.getRelationship().getType());
2410         Long creationDate = System.currentTimeMillis();
2411         relationshipInstData.setCreationTime(creationDate);
2412         relationshipInstData.setModificationTime(creationDate);
2413         relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId());
2414         relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId());
2415         relationshipInstData.setCapabilityId(relationPair.getCapabilityUid());
2416         relationshipInstData.setRequirementId(relationPair.getRequirementUid());
2417         relationshipInstData.setFromId(fromResInstanceUid);
2418         relationshipInstData.setToId(toInstId);
2419         relationshipInstData.setRequirement(relationPair.getRequirement());
2420         relationshipInstData.setCapability(relationPair.getCapability());
2421         relationshipInstData.setOriginUI(originUI);
2422         return relationshipInstData;
2423     }
2424
2425     public <T extends Component> Map<String, ComponentInstanceDataDefinition> associateComponentInstancesToComponent(Component containerComponent,
2426                                                                                                                      Map<ComponentInstance, T> componentInstanceTMap,
2427                                                                                                                      GraphVertex containerVertex,
2428                                                                                                                      boolean allowDeleted,
2429                                                                                                                      boolean isUpdateCsar) {
2430         String containerId = containerComponent.getUniqueId();
2431         Map<String, ComponentInstanceDataDefinition> instancesJsonData;
2432         Either<GraphVertex, JanusGraphOperationStatus> updateElement = null;
2433         if (!validateInstanceNames(componentInstanceTMap)) {
2434             throw new StorageException(StorageOperationStatus.INCONSISTENCY);
2435         }
2436         if (!allowDeleted && !validateDeletedResources(componentInstanceTMap)) {
2437             throw new StorageException(StorageOperationStatus.INCONSISTENCY);
2438         }
2439         instancesJsonData = convertToComponentInstanceDataDefinition(componentInstanceTMap, containerId, isUpdateCsar);
2440         if (MapUtils.isNotEmpty(instancesJsonData)) {
2441             containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
2442             Map<String, CompositionDataDefinition> compositions = new HashMap<>();
2443             CompositionDataDefinition composition = new CompositionDataDefinition();
2444             composition.setComponentInstances(instancesJsonData);
2445             compositions.put(JsonConstantKeysEnum.COMPOSITION.getValue(), composition);
2446             containerVertex.setJson(compositions);
2447             updateElement = janusGraphDao.updateVertex(containerVertex);
2448             if (updateElement.isRight()) {
2449                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update topology template {} with new component instances. ",
2450                     containerComponent.getName());
2451                 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateElement.right().value()));
2452             }
2453         }
2454         if (updateElement != null) {
2455             GraphVertex vertexC = updateElement.left().value();
2456             instancesJsonData.entrySet().forEach(i -> createInstanceEdge(vertexC, i.getValue()));
2457         }
2458         return instancesJsonData;
2459     }
2460
2461     private <T extends Component> Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(
2462         Map<ComponentInstance, T> componentInstanceTMap, String containerId, boolean isUpdateCsar) {
2463         Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
2464         for (Entry<ComponentInstance, T> entry : componentInstanceTMap.entrySet()) {
2465             ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null,
2466                 !isUpdateCsar || entry.getKey().isCreatedFromCsar(), ModelConverter.convertToToscaElement(entry.getValue()));
2467             instances.put(instance.getUniqueId(), instance);
2468         }
2469         return instances;
2470     }
2471
2472     private <T extends Component> boolean validateDeletedResources(Map<ComponentInstance, T> resourcesInstancesMap) {
2473         boolean result = true;
2474         for (Component component : resourcesInstancesMap.values()) {
2475             if (component.getIsDeleted() != null && component.getIsDeleted()) {
2476                 CommonUtility
2477                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", component.getName());
2478                 result = false;
2479                 break;
2480             }
2481         }
2482         return result;
2483     }
2484
2485     private <T extends Component> boolean validateInstanceNames(Map<ComponentInstance, T> resourcesInstancesMap) {
2486         boolean result = true;
2487         Set<String> names = new HashSet<>();
2488         for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
2489             if (StringUtils.isEmpty(instance.getName())) {
2490                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component instance {} name is empty. Cannot add component instance. ",
2491                     instance.getUniqueId());
2492                 result = false;
2493                 break;
2494             } else if (names.contains(instance.getName())) {
2495                 CommonUtility
2496                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Component instance with the name {} already exsists. Cannot add component instance. ",
2497                         instance.getName());
2498                 result = false;
2499                 break;
2500             } else {
2501                 names.add(instance.getName());
2502             }
2503         }
2504         return result;
2505     }
2506
2507     public StorageOperationStatus addDeploymentArtifactsToInstance(String toscaElementId, String instanceId,
2508                                                                    Map<String, ArtifactDataDefinition> instDeplArtifacts) {
2509         return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS,
2510             VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS);
2511     }
2512
2513     public StorageOperationStatus addInformationalArtifactsToInstance(String toscaElementId, String instanceId,
2514                                                                       Map<String, ArtifactDataDefinition> instDeplArtifacts) {
2515         return addArtifactsToInstance(toscaElementId, instanceId, instDeplArtifacts, EdgeLabelEnum.INSTANCE_ARTIFACTS,
2516             VertexTypeEnum.INSTANCE_ARTIFACTS);
2517     }
2518
2519     public StorageOperationStatus addArtifactsToInstance(String toscaElementId, String instanceId,
2520                                                          Map<String, ArtifactDataDefinition> instDeplArtifacts, EdgeLabelEnum edgeLabel,
2521                                                          VertexTypeEnum vertexType) {
2522         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
2523         if (metadataVertex.isRight()) {
2524             JanusGraphOperationStatus status = metadataVertex.right().value();
2525             if (status == JanusGraphOperationStatus.NOT_FOUND) {
2526                 status = JanusGraphOperationStatus.INVALID_ID;
2527             }
2528             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
2529         }
2530         MapArtifactDataDefinition instArtifacts = new MapArtifactDataDefinition(instDeplArtifacts);
2531         return addToscaDataDeepElementsBlockToToscaElement(metadataVertex.left().value(), edgeLabel, vertexType, instArtifacts, instanceId);
2532     }
2533
2534     @SuppressWarnings({"unchecked"})
2535     public StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId) {
2536         Either<GraphVertex, JanusGraphOperationStatus> metadataVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll);
2537         if (metadataVertex.isRight()) {
2538             JanusGraphOperationStatus status = metadataVertex.right().value();
2539             if (status == JanusGraphOperationStatus.NOT_FOUND) {
2540                 status = JanusGraphOperationStatus.INVALID_ID;
2541             }
2542             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
2543         }
2544         GraphVertex metaVertex = metadataVertex.left().value();
2545         Map<String, CompositionDataDefinition> json = (Map<String, CompositionDataDefinition>) metaVertex.getJson();
2546         CompositionDataDefinition compositionDataDefinition = json.get(JsonConstantKeysEnum.COMPOSITION.getValue());
2547         StorageOperationStatus status = updateCustomizationUUID(instanceId, compositionDataDefinition);
2548         if (status != StorageOperationStatus.OK) {
2549             log.debug("Failed to update customization UUID for instance {} in component {} error {}", instanceId, componentId, status);
2550             return status;
2551         }
2552         Either<GraphVertex, JanusGraphOperationStatus> updateVertex = janusGraphDao.updateVertex(metaVertex);
2553         if (updateVertex.isRight()) {
2554             log.debug("Failed to update vertex of component {} error {}", componentId, updateVertex.right().value());
2555             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateVertex.right().value());
2556         }
2557         return StorageOperationStatus.OK;
2558     }
2559
2560     public StorageOperationStatus generateCustomizationUUIDOnInstanceGroup(String componentId, String instanceId, List<String> groupInstances) {
2561         if (groupInstances != null) {
2562             Either<Map<String, MapGroupsDataDefinition>, JanusGraphOperationStatus> dataFromGraph = getDataFromGraph(componentId,
2563                 EdgeLabelEnum.INST_GROUPS);
2564             if (dataFromGraph.isRight()) {
2565                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
2566             }
2567             MapGroupsDataDefinition grInstPerInstance = dataFromGraph.left().value().get(instanceId);
2568             if (grInstPerInstance == null) {
2569                 log.debug("No  instance groups for instance {} in component {}", instanceId, componentId);
2570                 return StorageOperationStatus.NOT_FOUND;
2571             }
2572             for (String instGroupForUpdate : groupInstances) {
2573                 GroupInstanceDataDefinition groupInst = grInstPerInstance.findByKey(instGroupForUpdate);
2574                 if (groupInst == null) {
2575                     log.debug("No group instance {} in group list  for instance {} in component {}", instGroupForUpdate, instanceId, componentId);
2576                     continue;
2577                 }
2578                 UUID uuid = UUID.randomUUID();
2579                 groupInst.setCustomizationUUID(uuid.toString());
2580             }
2581         }
2582         return StorageOperationStatus.OK;
2583     }
2584
2585     public StorageOperationStatus addGroupInstancesToComponentInstance(Component containerComponent, ComponentInstance componentInstance,
2586                                                                        List<GroupInstance> groupInstances) {
2587         return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS,
2588             new MapDataDefinition<>(groupInstances.stream().collect(Collectors.toMap(GroupInstanceDataDefinition::getName, gi -> gi))),
2589             componentInstance.getUniqueId());
2590     }
2591
2592     public StorageOperationStatus addDeploymentArtifactsToComponentInstance(Component containerComponent, ComponentInstance componentInstance,
2593                                                                             Map<String, ArtifactDefinition> deploymentArtifacts) {
2594         return addToscaDataDeepElementsBlockToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS,
2595             VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, new MapDataDefinition<>(deploymentArtifacts), componentInstance.getUniqueId());
2596     }
2597
2598     public StorageOperationStatus updateComponentInstanceProperty(Component containerComponent, String componentInstanceId,
2599                                                                   ComponentInstanceProperty property) {
2600         List<String> pathKeys = new ArrayList<>();
2601         pathKeys.add(componentInstanceId);
2602         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES,
2603             VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
2604     }
2605
2606     public StorageOperationStatus updateComponentInstanceCapabilityProperty(Component containerComponent, String componentInstanceId,
2607                                                                             String capabilityPropertyKey, ComponentInstanceProperty property) {
2608         List<String> pathKeys = new ArrayList<>();
2609         pathKeys.add(componentInstanceId);
2610         pathKeys.add(capabilityPropertyKey);
2611         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
2612             VertexTypeEnum.CALCULATED_CAP_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME);
2613     }
2614
2615     public StorageOperationStatus overrideComponentCapabilitiesProperties(Component containerComponent,
2616                                                                           Map<String, MapCapabilityProperty> capabilityPropertyMap) {
2617         return overrideToscaDataOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, capabilityPropertyMap);
2618     }
2619
2620     public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId,
2621                                                                ComponentInstanceProperty property) {
2622         List<String> pathKeys = new ArrayList<>();
2623         pathKeys.add(componentInstanceId);
2624         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES,
2625             property, pathKeys, JsonPresentationFields.NAME);
2626     }
2627
2628     public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId,
2629                                                                     List<ComponentInstanceProperty> properties) {
2630         List<String> pathKeys = new ArrayList<>();
2631         pathKeys.add(componentInstanceId);
2632         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES,
2633             VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME);
2634     }
2635
2636     public StorageOperationStatus updateComponentInstanceAttributes(final Component containerComponent, final String componentInstanceId,
2637                                                                     final List<ComponentInstanceAttribute> attributes) {
2638         final List<String> pathKeys = Arrays.asList(componentInstanceId);
2639         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES,
2640             VertexTypeEnum.INST_ATTRIBUTES, attributes, pathKeys, JsonPresentationFields.NAME);
2641     }
2642
2643     public StorageOperationStatus updateComponentInstanceAttribute(final Component containerComponent, final String componentInstanceId,
2644                                                                    final ComponentInstanceAttribute attribute) {
2645         final List<String> pathKeys = Arrays.asList(componentInstanceId);
2646         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES,
2647             VertexTypeEnum.INST_ATTRIBUTES, attribute, pathKeys, JsonPresentationFields.NAME);
2648     }
2649
2650     public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId,
2651                                                                 ComponentInstanceAttribute attribute) {
2652         List<String> pathKeys = new ArrayList<>();
2653         pathKeys.add(componentInstanceId);
2654         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES,
2655             attribute, pathKeys, JsonPresentationFields.NAME);
2656     }
2657
2658     public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId,
2659                                                                ComponentInstanceInput property) {
2660         List<String> pathKeys = new ArrayList<>();
2661         pathKeys.add(componentInstanceId);
2662         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS,
2663             property, pathKeys, JsonPresentationFields.NAME);
2664     }
2665
2666     public StorageOperationStatus updateComponentInstanceOutput(Component containerComponent, String componentInstanceId,
2667                                                                 ComponentInstanceOutput property) {
2668         List<String> pathKeys = new ArrayList<>();
2669         pathKeys.add(componentInstanceId);
2670         return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS,
2671             property, pathKeys, JsonPresentationFields.NAME);
2672     }
2673
2674     public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId,
2675                                                                 List<ComponentInstanceInput> properties) {
2676         List<String> pathKeys = new ArrayList<>();
2677         pathKeys.add(componentInstanceId);
2678         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS,
2679             properties, pathKeys, JsonPresentationFields.NAME);
2680     }
2681
2682     public StorageOperationStatus updateComponentInstanceOutputs(Component containerComponent, String componentInstanceId,
2683                                                                  List<ComponentInstanceOutput> properties) {
2684         List<String> pathKeys = new ArrayList<>();
2685         pathKeys.add(componentInstanceId);
2686         return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS,
2687             properties, pathKeys, JsonPresentationFields.NAME);
2688     }
2689
2690     public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId,
2691                                                             ComponentInstanceInput property) {
2692         List<String> pathKeys = new ArrayList<>();
2693         pathKeys.add(componentInstanceId);
2694         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS,
2695             property, pathKeys, JsonPresentationFields.NAME);
2696     }
2697
2698     public StorageOperationStatus addComponentInstanceOutput(Component containerComponent, String componentInstanceId,
2699                                                              ComponentInstanceOutput property) {
2700         List<String> pathKeys = new ArrayList<>() {
2701         };
2702         pathKeys.add(componentInstanceId);
2703         return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS,
2704             property, pathKeys, JsonPresentationFields.NAME);
2705     }
2706
2707     public StorageOperationStatus createInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
2708         String instUniqueId = componentInstance.getUniqueId();
2709         // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
2710         StorageOperationStatus result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(),
2711             instUniqueId).either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2712         if (result == StorageOperationStatus.OK && componentInstance.getIsProxy()) {
2713             // create edge between container and service origin
2714             result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
2715                 .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2716         }
2717         return result;
2718     }
2719
2720     public StorageOperationStatus createAllottedOfEdge(String componentId, String instanceId, String serviceUUID) {
2721         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
2722         if (vertexById.isRight()) {
2723             log.debug("Failed to fetch component metadata vertex for id {} error {}", componentId, vertexById.right().value());
2724             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value());
2725         }
2726         GraphVertex metadataVertex = vertexById.left().value();
2727         EnumMap<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
2728         props.put(GraphPropertyEnum.UUID, serviceUUID);
2729         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
2730         EnumMap<GraphPropertyEnum, Object> hasNot = new EnumMap<>(GraphPropertyEnum.class);
2731         hasNot.put(GraphPropertyEnum.IS_DELETED, true);
2732         Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
2733             .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, props, hasNot, JsonParseFlagEnum.ParseMetadata);
2734         if (byCriteria.isRight()) {
2735             log.debug("Failed to fetch vertex by criteria {} error {}", props, byCriteria.right().value());
2736             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value());
2737         }
2738         List<GraphVertex> vertecies = byCriteria.left().value();
2739         StorageOperationStatus result = StorageOperationStatus.OK;
2740         if (vertecies != null) {
2741             GraphVertex serviceVertex = vertecies.get(0);
2742             //remove previous edges
2743             log.debug("Try to create or update edge between resource {} and service {} ", metadataVertex, serviceVertex.getUniqueId());
2744             // create edge between container and service reference
2745             result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.ALLOTTED_OF, serviceVertex.getUniqueId(), instanceId)
2746                 .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2747         }
2748         return result;
2749     }
2750
2751     public StorageOperationStatus removeInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
2752         String instUniqueId = componentInstance.getUniqueId();
2753         // create edge between container and origin ( in case of proxy this edge will be to ProxyService node type)
2754         StorageOperationStatus result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.INSTANCE_OF, componentInstance.getComponentUid(),
2755             instUniqueId).either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2756         if (componentInstance.getIsProxy()) {
2757             // create edge between container and service origin
2758             result = removeOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.PROXY_OF, componentInstance.getSourceModelUid(), instUniqueId)
2759                 .either(v -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
2760         }
2761         return result;
2762     }
2763
2764     private Either<GraphVertex, JanusGraphOperationStatus> createOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel,
2765                                                                                       String componentUid, String instUniqueId) {
2766         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
2767         properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
2768         return janusGraphDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties).left()
2769             .bind(v -> addInstanceToPropertyOnEdge(instUniqueId, v, metadataVertex)).right()
2770             .bind(s -> createInstanceEdge(metadataVertex, edgeLabel, componentUid, instUniqueId, s));
2771     }
2772
2773     private Either<GraphVertex, JanusGraphOperationStatus> removeOrUpdateInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel,
2774                                                                                       String componentUid, String instUniqueId) {
2775         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
2776         properties.put(GraphPropertyEnum.UNIQUE_ID, componentUid);
2777         return janusGraphDao.getEdgeByChildrenVertexProperties(metadataVertex, edgeLabel, properties).left()
2778             .bind(v -> removeInstanceFromPropertyOnEdge(instUniqueId, v, metadataVertex)).right()
2779             .map(err -> removeInstanceEdgeLogError(metadataVertex, edgeLabel, componentUid, err));
2780     }
2781
2782     private Either<GraphVertex, JanusGraphOperationStatus> addInstanceToPropertyOnEdge(String instUniqueId, Edge edge, GraphVertex metadataVertex) {
2783         // edge exist need to add instance id to list on edge's property
2784         List<String> property = (List<String>) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
2785         if (property == null) {
2786             property = new ArrayList<>();
2787         }
2788         Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
2789         if (!findFirst.isPresent()) {
2790             property.add(instUniqueId);
2791         }
2792         try {
2793             String jsonArr = JsonParserUtils.toJson(property);
2794             log.debug("Update INSTANCES edge property with value {} ", jsonArr);
2795             edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
2796         } catch (IOException e) {
2797             log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e);
2798             return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
2799         }
2800         return Either.left(metadataVertex);
2801     }
2802
2803     private Either<GraphVertex, JanusGraphOperationStatus> removeInstanceFromPropertyOnEdge(String instUniqueId, Edge edge,
2804                                                                                             GraphVertex metadataVertex) {
2805         // edge exist need to add instance id to list on edge's property
2806         List<String> property = (List<String>) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES);
2807         if (property == null) {
2808             property = new ArrayList<>();
2809         }
2810         Optional<String> findFirst = property.stream().filter(a -> a.equals(instUniqueId)).findFirst();
2811         if (findFirst.isPresent()) {
2812             property.remove(instUniqueId);
2813         }
2814         if (property.isEmpty()) {
2815             // For last instance need to remove edge
2816             edge.remove();
2817         } else {
2818             try {
2819                 String jsonArr = JsonParserUtils.toJson(property);
2820                 edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
2821             } catch (IOException e) {
2822                 log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e);
2823                 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
2824             }
2825         }
2826         return Either.left(metadataVertex);
2827     }
2828
2829     private Either<GraphVertex, JanusGraphOperationStatus> createInstanceEdge(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel,
2830                                                                               String componentUid, String instUniqueId,
2831                                                                               JanusGraphOperationStatus retrieveEdgeStatus) {
2832         if (retrieveEdgeStatus == JanusGraphOperationStatus.NOT_FOUND) {
2833             // create new edge
2834             Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentUid);
2835             if (vertexById.isRight()) {
2836                 return vertexById;
2837             }
2838             GraphVertex originVertex = vertexById.left().value();
2839             Map<EdgePropertyEnum, Object> edgeProps = new EnumMap<>(EdgePropertyEnum.class);
2840             List<String> instList = new ArrayList<>();
2841             instList.add(instUniqueId);
2842             edgeProps.put(EdgePropertyEnum.INSTANCES, instList);
2843             log.debug("Create new edge {} between {} and {} and properties {} ", edgeLabel, metadataVertex.getUniqueId(), originVertex.getUniqueId(),
2844                 edgeProps);
2845             JanusGraphOperationStatus edgeResult = janusGraphDao.createEdge(metadataVertex, originVertex, edgeLabel, edgeProps);
2846             return edgeResult == JanusGraphOperationStatus.OK ? Either.left(metadataVertex) : Either.right(edgeResult);
2847         }
2848         // error
2849         log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
2850         return Either.right(retrieveEdgeStatus);
2851     }
2852
2853     private JanusGraphOperationStatus removeInstanceEdgeLogError(GraphVertex metadataVertex, EdgeLabelEnum edgeLabel, String componentUid,
2854                                                                  JanusGraphOperationStatus retrieveEdgeStatus) {
2855         if (retrieveEdgeStatus == JanusGraphOperationStatus.NOT_FOUND) {
2856             log.debug("No edge {} to remove between container {} and origin {}", edgeLabel, metadataVertex.getUniqueId(), componentUid);
2857         } else {
2858             // error
2859             log.debug("Failed to fetch edge with label {} and to vertex with id {} error {} ", edgeLabel, componentUid, retrieveEdgeStatus);
2860         }
2861         return retrieveEdgeStatus;
2862     }
2863
2864     public void removeAllAllotedEdges(String uniqueId) {
2865         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(uniqueId);
2866         if (vertexById.isLeft()) {
2867             GraphVertex originVertex = vertexById.left().value();
2868             JanusGraphVertex vertex = originVertex.getVertex();
2869             Iterator<Edge> edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name());
2870             while (edges != null && edges.hasNext()) {
2871                 Edge edge = edges.next();
2872                 edge.remove();
2873             }
2874         }
2875     }
2876 }