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