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