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