Fix for VFC version update on composition window
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentInstanceBusinessLogic.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.components.impl;
21
22 import static org.openecomp.sdc.be.components.attribute.GetOutputUtils.isGetOutputValueForOutput;
23 import static org.openecomp.sdc.be.components.property.GetInputUtils.isGetInputValueForInput;
24 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.getPropertyCapabilityOfChildInstance;
25
26 import com.google.common.collect.Sets;
27 import fj.data.Either;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import java.util.Objects;
38 import java.util.Optional;
39 import java.util.Set;
40 import java.util.UUID;
41 import java.util.stream.Collectors;
42 import org.apache.commons.collections.CollectionUtils;
43 import org.apache.commons.collections.MapUtils;
44 import org.apache.commons.lang3.StringUtils;
45 import org.apache.commons.lang3.tuple.ImmutablePair;
46 import org.json.JSONObject;
47 import org.onap.sdc.tosca.datatypes.model.PropertyType;
48 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
49 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
50 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
51 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
52 import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier;
53 import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator;
54 import org.openecomp.sdc.be.components.impl.utils.DirectivesUtil;
55 import org.openecomp.sdc.be.components.merge.instance.ComponentInstanceMergeDataBusinessLogic;
56 import org.openecomp.sdc.be.components.merge.instance.DataForMergeHolder;
57 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
58 import org.openecomp.sdc.be.components.validation.ComponentValidations;
59 import org.openecomp.sdc.be.config.BeEcompErrorManager;
60 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
61 import org.openecomp.sdc.be.config.ConfigurationManager;
62 import org.openecomp.sdc.be.dao.api.ActionStatus;
63 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
64 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
65 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
66 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
69 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
70 import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition;
71 import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition;
72 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
73 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
74 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
75 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
76 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
77 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
78 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
79 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
80 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
81 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
82 import org.openecomp.sdc.be.exception.BusinessException;
83 import org.openecomp.sdc.be.impl.ComponentsUtils;
84 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
85 import org.openecomp.sdc.be.impl.ServiceFilterUtils;
86 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
87 import org.openecomp.sdc.be.model.ArtifactDefinition;
88 import org.openecomp.sdc.be.model.AttributeDefinition;
89 import org.openecomp.sdc.be.model.CapabilityDefinition;
90 import org.openecomp.sdc.be.model.Component;
91 import org.openecomp.sdc.be.model.ComponentInstance;
92 import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
93 import org.openecomp.sdc.be.model.ComponentInstanceInput;
94 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
95 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
96 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
97 import org.openecomp.sdc.be.model.ComponentParametersView;
98 import org.openecomp.sdc.be.model.DataTypeDefinition;
99 import org.openecomp.sdc.be.model.GroupDefinition;
100 import org.openecomp.sdc.be.model.InputDefinition;
101 import org.openecomp.sdc.be.model.InterfaceDefinition;
102 import org.openecomp.sdc.be.model.LifecycleStateEnum;
103 import org.openecomp.sdc.be.model.OutputDefinition;
104 import org.openecomp.sdc.be.model.PolicyDefinition;
105 import org.openecomp.sdc.be.model.PropertyDefinition;
106 import org.openecomp.sdc.be.model.RelationshipInfo;
107 import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
108 import org.openecomp.sdc.be.model.RequirementDefinition;
109 import org.openecomp.sdc.be.model.Resource;
110 import org.openecomp.sdc.be.model.Service;
111 import org.openecomp.sdc.be.model.ToscaPropertyData;
112 import org.openecomp.sdc.be.model.User;
113 import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData;
114 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
115 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
116 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
117 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
118 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
119 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
120 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
121 import org.openecomp.sdc.be.model.operations.StorageException;
122 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
123 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
124 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
125 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
126 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
127 import org.openecomp.sdc.be.model.operations.impl.ComponentInstanceOperation;
128 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
129 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
130 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
131 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
132 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
133 import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
134 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
135 import org.openecomp.sdc.be.user.Role;
136 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
137 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
138 import org.openecomp.sdc.common.api.Constants;
139 import org.openecomp.sdc.common.datastructure.Wrapper;
140 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
141 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
142 import org.openecomp.sdc.common.log.elements.ErrorLogOptionalData;
143 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
144 import org.openecomp.sdc.common.log.wrappers.Logger;
145 import org.openecomp.sdc.common.util.ValidationUtils;
146 import org.openecomp.sdc.exception.ResponseFormat;
147 import org.springframework.beans.factory.annotation.Autowired;
148 import org.yaml.snakeyaml.Yaml;
149
150 @org.springframework.stereotype.Component
151 public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
152
153     private static final Logger log = Logger.getLogger(ComponentInstanceBusinessLogic.class);
154     private static final String VF_MODULE = "org.openecomp.groups.VfModule";
155     private static final String TRY_TO_CREATE_ENTRY_ON_GRAPH = "Try to create entry on graph";
156     private static final String CLOUD_SPECIFIC_FIXED_KEY_WORD = "cloudtech";
157     private static final String[][] CLOUD_SPECIFIC_KEY_WORDS = {{"k8s", "azure", "aws"}, /* cloud specific technology */
158         {"charts", "day0", "configtemplate"} /*cloud specific sub type*/};
159     private static final String FAILED_TO_CREATE_ENTRY_ON_GRAPH_FOR_COMPONENT_INSTANCE = "Failed to create entry on graph for component instance {}";
160     private static final String ENTITY_ON_GRAPH_IS_CREATED = "Entity on graph is created.";
161     private static final String INVALID_COMPONENT_TYPE = "invalid component type";
162     private static final String FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID = "Failed to retrieve component, component id {}";
163     private static final String FAILED_TO_LOCK_SERVICE = "Failed to lock service {}";
164     private static final String CREATE_OR_UPDATE_PROPERTY_VALUE = "CreateOrUpdatePropertyValue";
165     private static final String FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS = "Failed to copy the component instance to the canvas";
166     private static final String COPY_COMPONENT_INSTANCE_OK = "Copy component instance OK";
167     private static final String CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE = "Cannot attach resource instances to container resource of type {}";
168     private static final String FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY = "Failed to update component instance capability on instance {} in "
169         + "container {}";
170     private static final String SERVICE_PROXY = "serviceProxy";
171     private static final String ASSOCIATE_RI_TO_RI = "associateRIToRI";
172     private static final String COMPONENT_ARCHIVED = "Component is archived. Component id: {}";
173     private static final String RESTRICTED_OPERATION_ON_SERVIVE = "Restricted operation for user: {} on service {}";
174     private static final String FAILED_TO_LOCK_COMPONENT = "Failed to lock component {}";
175     private static final String RESTRICTED_OPERATION_ON_COMPONENT = "Restricted operation for user: {} on component {}";
176     private static final String RESOURCE_INSTANCE = "resource instance";
177     private static final String SERVICE = "service";
178
179     private final ComponentInstanceOperation componentInstanceOperation;
180     private final ArtifactsBusinessLogic artifactBusinessLogic;
181     private final ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
182     private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
183     private final ForwardingPathOperation forwardingPathOperation;
184     private final NodeFilterOperation nodeFilterOperation;
185     @Autowired
186     private CompositionBusinessLogic compositionBusinessLogic;
187     @Autowired
188     private ContainerInstanceTypesData containerInstanceTypesData;
189     private final ToscaFunctionValidator toscaFunctionValidator;
190
191     @Autowired
192     public ComponentInstanceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
193                                           IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
194                                           InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
195                                           ComponentInstanceOperation componentInstanceOperation, ArtifactsBusinessLogic artifactBusinessLogic,
196                                           ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL,
197                                           ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator,
198                                           ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation,
199                                           ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator) {
200         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
201             artifactToscaOperation);
202         this.componentInstanceOperation = componentInstanceOperation;
203         this.artifactBusinessLogic = artifactBusinessLogic;
204         this.compInstMergeDataBL = compInstMergeDataBL;
205         this.onChangeInstanceOperationOrchestrator = onChangeInstanceOperationOrchestrator;
206         this.forwardingPathOperation = forwardingPathOperation;
207         this.nodeFilterOperation = nodeFilterOperation;
208         this.toscaFunctionValidator = toscaFunctionValidator;
209     }
210
211     public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId,
212                                                      ComponentInstance resourceInstance) {
213         return createComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, true);
214     }
215
216     public List<ComponentInstanceProperty> getComponentInstancePropertiesByInputId(org.openecomp.sdc.be.model.Component component, String inputId) {
217         List<ComponentInstanceProperty> resList = new ArrayList<>();
218         Map<String, List<ComponentInstanceProperty>> ciPropertiesMap = component.getComponentInstancesProperties();
219         if (ciPropertiesMap != null && !ciPropertiesMap.isEmpty()) {
220             ciPropertiesMap.forEach((s, ciPropList) -> {
221                 String ciName = "";
222                 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)).findAny();
223                 if (ciOp.isPresent()) {
224                     ciName = ciOp.get().getName();
225                 }
226                 if (ciPropList != null && !ciPropList.isEmpty()) {
227                     for (ComponentInstanceProperty prop : ciPropList) {
228                         List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues();
229                         addCompInstanceProperty(s, ciName, prop, inputsValues, inputId, resList);
230                     }
231                 }
232             });
233         }
234         return resList;
235     }
236
237     public List<ComponentInstanceAttribute> getComponentInstanceAttributesByOutputId(final org.openecomp.sdc.be.model.Component component,
238                                                                                      final String outputId) {
239         final List<ComponentInstanceAttribute> resList = new ArrayList<>();
240         final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes();
241         if (org.apache.commons.collections4.MapUtils.isNotEmpty(componentInstancesAttributes)) {
242             componentInstancesAttributes.forEach((s, componentInstanceAttributeList) -> {
243                 String ciName = "";
244                 final Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s))
245                     .findAny();
246                 if (ciOp.isPresent()) {
247                     ciName = ciOp.get().getName();
248                 }
249                 if (componentInstanceAttributeList != null && !componentInstanceAttributeList.isEmpty()) {
250                     for (final ComponentInstanceAttribute compInstanceAttribute : componentInstanceAttributeList) {
251                         List<GetOutputValueDataDefinition> outputValues = compInstanceAttribute.getGetOutputValues();
252                         addCompInstanceAttribute(s, ciName, compInstanceAttribute, outputValues, outputId, resList);
253                     }
254                 }
255             });
256         }
257         return resList;
258     }
259
260     private void addCompInstanceProperty(String s, String ciName, ComponentInstanceProperty prop, List<GetInputValueDataDefinition> inputsValues,
261                                          String inputId, List<ComponentInstanceProperty> resList) {
262         if (inputsValues != null && !inputsValues.isEmpty()) {
263             for (GetInputValueDataDefinition inputData : inputsValues) {
264                 if (isGetInputValueForInput(inputData, inputId)) {
265                     prop.setComponentInstanceId(s);
266                     prop.setComponentInstanceName(ciName);
267                     resList.add(prop);
268                     break;
269                 }
270             }
271         }
272     }
273
274     private void addCompInstanceAttribute(final String s, final String ciName, final ComponentInstanceAttribute attribute,
275                                           final List<GetOutputValueDataDefinition> outputsValues, final String outputId,
276                                           final List<ComponentInstanceAttribute> resList) {
277         if (outputsValues != null && !outputsValues.isEmpty()) {
278             for (final GetOutputValueDataDefinition outputData : outputsValues) {
279                 if (isGetOutputValueForOutput(outputData, outputId)) {
280                     attribute.setComponentInstanceId(s);
281                     attribute.setComponentInstanceName(ciName);
282                     resList.add(attribute);
283                     break;
284                 }
285             }
286         }
287     }
288
289     public Optional<ComponentInstanceProperty> getComponentInstancePropertyByPolicyId(Component component, PolicyDefinition policy) {
290         Optional<ComponentInstanceProperty> propertyCandidate = getComponentInstancePropertyByPolicy(component, policy);
291         if (propertyCandidate.isPresent()) {
292             ComponentInstanceProperty componentInstanceProperty = propertyCandidate.get();
293             Optional<GetPolicyValueDataDefinition> getPolicyCandidate = getGetPolicyValueDataDefinition(policy, componentInstanceProperty);
294             getPolicyCandidate
295                 .ifPresent(getPolicyValue -> updateComponentInstancePropertyAfterUndeclaration(componentInstanceProperty, getPolicyValue, policy));
296             return Optional.of(componentInstanceProperty);
297         }
298         return Optional.empty();
299     }
300
301     private void updateComponentInstancePropertyAfterUndeclaration(ComponentInstanceProperty componentInstanceProperty,
302                                                                    GetPolicyValueDataDefinition getPolicyValue, PolicyDefinition policyDefinition) {
303         componentInstanceProperty.setValue(getPolicyValue.getOrigPropertyValue());
304         List<GetPolicyValueDataDefinition> getPolicyValues = componentInstanceProperty.getGetPolicyValues();
305         if (CollectionUtils.isNotEmpty(getPolicyValues)) {
306             getPolicyValues.remove(getPolicyValue);
307             componentInstanceProperty.setGetPolicyValues(getPolicyValues);
308             policyDefinition.setGetPolicyValues(getPolicyValues);
309         }
310     }
311
312     private Optional<GetPolicyValueDataDefinition> getGetPolicyValueDataDefinition(PolicyDefinition policy,
313                                                                                    ComponentInstanceProperty componentInstanceProperty) {
314         List<GetPolicyValueDataDefinition> getPolicyValues = policy.getGetPolicyValues();
315         return getPolicyValues.stream().filter(getPolicyValue -> getPolicyValue.getPropertyName().equals(componentInstanceProperty.getName()))
316             .findAny();
317     }
318
319     private Optional<ComponentInstanceProperty> getComponentInstancePropertyByPolicy(Component component, PolicyDefinition policy) {
320         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties();
321         if (MapUtils.isEmpty(componentInstancesProperties)) {
322             return Optional.empty();
323         }
324         String instanceUniqueId = policy.getInstanceUniqueId();
325         List<ComponentInstanceProperty> componentInstanceProperties =
326             componentInstancesProperties.containsKey(instanceUniqueId) ? componentInstancesProperties.get(instanceUniqueId) : new ArrayList<>();
327         return componentInstanceProperties.stream().filter(property -> property.getName().equals(policy.getName())).findAny();
328     }
329
330     public List<ComponentInstanceInput> getComponentInstanceInputsByInputId(org.openecomp.sdc.be.model.Component component, String inputId) {
331         List<ComponentInstanceInput> resList = new ArrayList<>();
332         Map<String, List<ComponentInstanceInput>> ciInputsMap = component.getComponentInstancesInputs();
333         if (ciInputsMap != null && !ciInputsMap.isEmpty()) {
334             ciInputsMap.forEach((s, ciPropList) -> {
335                 String ciName = "";
336                 Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)).findAny();
337                 if (ciOp.isPresent()) {
338                     ciName = ciOp.get().getName();
339                 }
340                 if (ciPropList != null && !ciPropList.isEmpty()) {
341                     for (ComponentInstanceInput prop : ciPropList) {
342                         List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues();
343                         addCompInstanceInput(s, ciName, prop, inputsValues, inputId, resList);
344                     }
345                 }
346             });
347         }
348         return resList;
349     }
350
351     public List<ComponentInstanceOutput> getComponentInstanceOutputsByOutputId(final org.openecomp.sdc.be.model.Component component,
352                                                                                final String outputId) {
353         final List<ComponentInstanceOutput> resList = new ArrayList<>();
354         final Map<String, List<ComponentInstanceOutput>> ciInputsMap = component.getComponentInstancesOutputs();
355         if (ciInputsMap != null && !ciInputsMap.isEmpty()) {
356             ciInputsMap.forEach((s, ciPropList) -> {
357                 String ciName = "";
358                 final Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s))
359                     .findAny();
360                 if (ciOp.isPresent()) {
361                     ciName = ciOp.get().getName();
362                 }
363                 if (ciPropList != null && !ciPropList.isEmpty()) {
364                     for (final ComponentInstanceOutput prop : ciPropList) {
365                         final List<GetOutputValueDataDefinition> outputValues = prop.getGetOutputValues();
366                         addCompInstanceOutput(s, ciName, prop, outputValues, outputId, resList);
367                     }
368                 }
369             });
370         }
371         return resList;
372     }
373
374     private void addCompInstanceInput(String s, String ciName, ComponentInstanceInput prop, List<GetInputValueDataDefinition> inputsValues,
375                                       String inputId, List<ComponentInstanceInput> resList) {
376         if (inputsValues != null && !inputsValues.isEmpty()) {
377             for (GetInputValueDataDefinition inputData : inputsValues) {
378                 if (isGetInputValueForInput(inputData, inputId)) {
379                     prop.setComponentInstanceId(s);
380                     prop.setComponentInstanceName(ciName);
381                     resList.add(prop);
382                     break;
383                 }
384             }
385         }
386     }
387
388     private void addCompInstanceOutput(final String s, final String ciName, final ComponentInstanceOutput prop,
389                                        final List<GetOutputValueDataDefinition> outputsValues, final String outputId,
390                                        final List<ComponentInstanceOutput> resList) {
391         if (outputsValues != null && !outputsValues.isEmpty()) {
392             for (final GetOutputValueDataDefinition outputData : outputsValues) {
393                 if (isGetOutputValueForOutput(outputData, outputId)) {
394                     prop.setComponentInstanceId(s);
395                     prop.setComponentInstanceName(ciName);
396                     resList.add(prop);
397                     break;
398                 }
399             }
400         }
401     }
402
403     public ComponentInstance createComponentInstance(final String containerComponentParam, final String containerComponentId, final String userId,
404                                                      final ComponentInstance resourceInstance, final boolean needLock) {
405         final User user = validateUserExists(userId);
406         validateUserNotEmpty(user, "Create component instance");
407         validateJsonBody(resourceInstance, ComponentInstance.class);
408         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
409         final org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
410         if (ModelConverter.isAtomicComponent(containerComponent)) {
411             if (log.isDebugEnabled()) {
412                 log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType());
413             }
414             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType());
415         }
416         validateCanWorkOnComponent(containerComponent, userId);
417         Component origComponent = null;
418         if (resourceInstance != null && containerComponentType != null) {
419             final OriginTypeEnum originType = resourceInstance.getOriginType();
420             validateInstanceName(resourceInstance);
421             if (originType == OriginTypeEnum.ServiceProxy) {
422                 origComponent = getOrigComponentForServiceProxy(containerComponent, resourceInstance);
423             } else if (originType == OriginTypeEnum.ServiceSubstitution) {
424                 origComponent = getOrigComponentForServiceSubstitution(resourceInstance);
425             } else {
426                 origComponent = getAndValidateOriginComponentOfComponentInstance(containerComponent, resourceInstance);
427                 validateOriginAndResourceInstanceTypes(containerComponent, origComponent, originType);
428             }
429             validateResourceInstanceState(containerComponent, origComponent);
430             overrideFields(origComponent, resourceInstance);
431             compositionBusinessLogic.validateAndSetDefaultCoordinates(resourceInstance);
432         }
433         return createComponent(needLock, containerComponent, origComponent, resourceInstance, user);
434     }
435
436     private Component getOrigComponentForServiceProxy(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance resourceInstance) {
437         Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY, null);
438         if (isServiceProxyOrigin(serviceProxyOrigin)) {
439             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
440         }
441         Component origComponent = serviceProxyOrigin.left().value();
442         StorageOperationStatus fillProxyRes = fillInstanceData(resourceInstance, origComponent);
443         if (isFillProxyRes(fillProxyRes)) {
444             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(fillProxyRes));
445         }
446         validateOriginAndResourceInstanceTypes(containerComponent, origComponent, OriginTypeEnum.ServiceProxy);
447         return origComponent;
448     }
449
450     private Component getOrigComponentForServiceSubstitution(ComponentInstance resourceInstance) {
451         final Either<Component, StorageOperationStatus> getServiceResult = toscaOperationFacade
452             .getToscaFullElement(resourceInstance.getComponentUid());
453         if (getServiceResult.isRight()) {
454             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
455         }
456         final Component service = getServiceResult.left().value();
457         final Either<Component, StorageOperationStatus> getServiceDerivedFromTypeResult = toscaOperationFacade
458             .getLatestByToscaResourceName(service.getDerivedFromGenericType(), service.getModel());
459         if (getServiceDerivedFromTypeResult.isRight()) {
460             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
461         }
462         Component origComponent = getServiceDerivedFromTypeResult.left().value();
463         final StorageOperationStatus fillProxyRes = fillInstanceData(resourceInstance, origComponent);
464         if (isFillProxyRes(fillProxyRes)) {
465             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(fillProxyRes));
466         }
467         return origComponent;
468     }
469
470     private ComponentInstance createComponent(boolean needLock, Component containerComponent, Component origComponent,
471                                               ComponentInstance resourceInstance, User user) {
472         boolean failed = false;
473         try {
474             lockIfNeed(needLock, containerComponent);
475             log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH);
476             return createComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, user);
477         } catch (ComponentException e) {
478             failed = true;
479             throw e;
480         } finally {
481             if (needLock) {
482                 unlockComponent(failed, containerComponent);
483             }
484         }
485     }
486
487     /**
488      * Try using either to make a judgment
489      *
490      * @param containerComponentParam
491      * @param containerComponentId
492      * @param userId
493      * @param resourceInstance
494      * @return
495      */
496     public Either<ComponentInstance, ResponseFormat> createRealComponentInstance(String containerComponentParam, String containerComponentId,
497                                                                                  String userId, ComponentInstance resourceInstance) {
498         log.debug("enter createRealComponentInstance");
499         return createRealComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, true);
500     }
501
502     /**
503      * Try using either to make a judgment
504      *
505      * @param needLock
506      * @param containerComponentParam
507      * @param containerComponentId
508      * @param userId
509      * @param resourceInstance
510      * @return
511      */
512     public Either<ComponentInstance, ResponseFormat> createRealComponentInstance(String containerComponentParam, String containerComponentId,
513                                                                                  String userId, ComponentInstance resourceInstance,
514                                                                                  boolean needLock) {
515         log.debug("enter createRealComponentInstance");
516         Component origComponent = null;
517         User user;
518         org.openecomp.sdc.be.model.Component containerComponent = null;
519         ComponentTypeEnum containerComponentType;
520         try {
521             user = validateUserExists(userId);
522             validateUserNotEmpty(user, "Create component instance");
523             validateJsonBody(resourceInstance, ComponentInstance.class);
524             containerComponentType = validateComponentType(containerComponentParam);
525             containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
526             log.debug("enter createRealComponentInstance,validate user json success");
527             if (ModelConverter.isAtomicComponent(containerComponent)) {
528                 log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType());
529                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType());
530             }
531             validateCanWorkOnComponent(containerComponent, userId);
532             log.debug("enter createRealComponentInstance,validateCanWorkOnComponent success");
533             if (resourceInstance != null && containerComponentType != null) {
534                 log.debug("enter createRealComponentInstance,start create ComponentInstance");
535                 OriginTypeEnum originType = resourceInstance.getOriginType();
536                 validateInstanceName(resourceInstance);
537                 if (originType == OriginTypeEnum.ServiceProxy) {
538                     log.debug("enter createRealComponentInstance,originType equals ServiceProxy");
539                     Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY, null);
540                     if (isServiceProxyOrigin(serviceProxyOrigin)) {
541                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
542                     }
543                     origComponent = serviceProxyOrigin.left().value();
544                     StorageOperationStatus fillProxyRes = fillInstanceData(resourceInstance, origComponent);
545                     if (isFillProxyRes(fillProxyRes)) {
546                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(fillProxyRes));
547                     }
548                 } else {
549                     log.debug("enter createRealComponentInstance,originType is not ServiceProxy");
550                     origComponent = getAndValidateOriginComponentOfComponentInstance(containerComponent, resourceInstance);
551                 }
552                 validateOriginAndResourceInstanceTypes(containerComponent, origComponent, originType);
553                 validateResourceInstanceState(containerComponent, origComponent);
554                 overrideFields(origComponent, resourceInstance);
555                 compositionBusinessLogic.validateAndSetDefaultCoordinates(resourceInstance);
556                 log.debug("enter createRealComponentInstance,final validate success");
557             }
558             return createRealComponent(needLock, containerComponent, origComponent, resourceInstance, user);
559         } catch (ComponentException e) {
560             log.debug("create Real Component Instance failed");
561             throw e;
562         }
563     }
564
565     private Either<ComponentInstance, ResponseFormat> createRealComponent(boolean needLock, Component containerComponent, Component origComponent,
566                                                                           ComponentInstance resourceInstance, User user) {
567         log.debug("enter createRealComponent");
568         boolean failed = false;
569         try {
570             lockIfNeed(needLock, containerComponent);
571             log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH);
572             return createRealComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, user);
573         } catch (ComponentException e) {
574             failed = true;
575             throw e;
576         } finally {
577             if (needLock) {
578                 unlockComponent(failed, containerComponent);
579             }
580         }
581     }
582
583     private Either<ComponentInstance, ResponseFormat> createRealComponentInstanceOnGraph(org.openecomp.sdc.be.model.Component containerComponent,
584                                                                                          Component originComponent,
585                                                                                          ComponentInstance componentInstance, User user) {
586         log.debug("enter createRealComponentInstanceOnGraph");
587         Either<ImmutablePair<Component, String>, StorageOperationStatus> result = toscaOperationFacade
588             .addComponentInstanceToTopologyTemplate(containerComponent, originComponent, componentInstance, false, user);
589         if (result.isRight()) {
590             log.debug("enter createRealComponentInstanceOnGraph,result is right");
591             ActionStatus status = componentsUtils.convertFromStorageResponse(result.right().value());
592             log.debug(FAILED_TO_CREATE_ENTRY_ON_GRAPH_FOR_COMPONENT_INSTANCE, componentInstance.getName());
593             return Either.right(componentsUtils.getResponseFormat(status));
594         }
595         log.debug(ENTITY_ON_GRAPH_IS_CREATED);
596         log.debug("enter createRealComponentInstanceOnGraph,Entity on graph is created.");
597         Component updatedComponent = result.left().value().getLeft();
598         Map<String, String> existingEnvVersions = new HashMap<>();
599         // TODO existingEnvVersions ??
600         addComponentInstanceArtifacts(updatedComponent, componentInstance, originComponent, user, existingEnvVersions);
601         Optional<ComponentInstance> updatedInstanceOptional = updatedComponent.getComponentInstances().stream()
602             .filter(ci -> ci.getUniqueId().equals(result.left().value().getRight())).findFirst();
603         if (!updatedInstanceOptional.isPresent()) {
604             log.debug("Failed to fetch new added component instance {} from component {}", componentInstance.getName(), containerComponent.getName());
605             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName());
606         }
607         log.debug("enter createRealComponentInstanceOnGraph,and final success");
608         return Either.left(updatedInstanceOptional.get());
609     }
610
611     private void overrideFields(Component origComponent, ComponentInstance resourceInstance) {
612         resourceInstance.setComponentVersion(origComponent.getVersion());
613         resourceInstance.setIcon(origComponent.getIcon());
614     }
615
616     private void validateInstanceName(ComponentInstance resourceInstance) {
617         String resourceInstanceName = resourceInstance.getName();
618         if (StringUtils.isEmpty(resourceInstanceName)) {
619             log.debug("ComponentInstance name is empty");
620             throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPONENT_NAME, resourceInstance.getName());
621         }
622         if (!ValidationUtils.validateComponentNameLength(resourceInstanceName)) {
623             log.debug("ComponentInstance name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
624             throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPONENT_NAME, resourceInstance.getName());
625         }
626         if (!ValidationUtils.validateComponentNamePattern(resourceInstanceName)) {
627             log.debug("ComponentInstance name {} has invalid format", resourceInstanceName);
628             throw new ByActionStatusComponentException(ActionStatus.INVALID_COMPONENT_NAME, resourceInstance.getName());
629         }
630     }
631
632     private void validateResourceInstanceState(Component containerComponent, Component origComponent) {
633         if (origComponent.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
634             throw new ByActionStatusComponentException(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE,
635                 containerComponent.getComponentType().getValue(), origComponent.getLifecycleState().toString());
636         }
637     }
638
639     private void validateOriginAndResourceInstanceTypes(final Component containerComponent, final Component origComponent,
640                                                         final OriginTypeEnum originType) {
641         final ResourceTypeEnum resourceType = getResourceTypeEnumFromOriginComponent(origComponent);
642         validateOriginType(originType, resourceType);
643         validateOriginComponentIsValidForContainer(containerComponent, resourceType);
644     }
645
646     private void validateOriginComponentIsValidForContainer(Component containerComponent, ResourceTypeEnum resourceType) {
647         switch (containerComponent.getComponentType()) {
648             case SERVICE:
649                 if (!containerInstanceTypesData.isAllowedForServiceComponent(resourceType, containerComponent.getModel())) {
650                     throw new ByActionStatusComponentException(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE,
651                         containerComponent.getComponentType().toString(), resourceType.name());
652                 }
653                 break;
654             case RESOURCE:
655                 final ResourceTypeEnum componentResourceType = ((Resource) containerComponent).getResourceType();
656                 if (!containerInstanceTypesData.isAllowedForResourceComponent(componentResourceType, resourceType)) {
657                     throw new ByActionStatusComponentException(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE,
658                         containerComponent.getComponentType().toString(), resourceType.name());
659                 }
660                 break;
661             default:
662                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
663         }
664     }
665
666     private void validateOriginType(OriginTypeEnum originType, ResourceTypeEnum resourceType) {
667         ResourceTypeEnum convertedOriginType;
668         try {
669             convertedOriginType = ResourceTypeEnum.getTypeIgnoreCase(originType.name());
670         } catch (Exception e) {
671             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
672         }
673         if (resourceType != convertedOriginType) {
674             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
675         }
676     }
677
678     private ResourceTypeEnum getResourceTypeEnumFromOriginComponent(final Component origComponent) {
679         switch (origComponent.getComponentType()) {
680             case SERVICE:
681                 return ResourceTypeEnum.ServiceProxy;
682             case RESOURCE:
683                 return ((Resource) origComponent).getResourceType();
684             default:
685                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
686         }
687     }
688
689     private void lockIfNeed(boolean needLock, Component containerComponent) {
690         if (needLock) {
691             lockComponent(containerComponent, "createComponentInstance");
692         }
693     }
694
695     private boolean isServiceProxyOrigin(Either<Component, StorageOperationStatus> serviceProxyOrigin) {
696         if (serviceProxyOrigin.isRight()) {
697             log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", serviceProxyOrigin.right().value());
698             return true;
699         }
700         return false;
701     }
702
703     private StorageOperationStatus fillInstanceData(ComponentInstance resourceInstance, Component origComponent) {
704         final ComponentParametersView filter = new ComponentParametersView(true);
705         filter.setIgnoreCapabilities(false);
706         filter.setIgnoreCapabiltyProperties(false);
707         filter.setIgnoreComponentInstances(false);
708         filter.setIgnoreRequirements(false);
709         filter.setIgnoreInterfaces(false);
710         filter.setIgnoreProperties(false);
711         filter.setIgnoreAttributes(false);
712         filter.setIgnoreInputs(false);
713         Either<Component, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(resourceInstance.getComponentUid(), filter);
714         if (serviceRes.isRight()) {
715             return serviceRes.right().value();
716         }
717         final Component service = serviceRes.left().value();
718         final Map<String, List<CapabilityDefinition>> capabilities = service.getCapabilities();
719         resourceInstance.setCapabilities(capabilities);
720         final Map<String, List<RequirementDefinition>> req = service.getRequirements();
721         resourceInstance.setRequirements(req);
722         final Map<String, InterfaceDefinition> serviceInterfaces = service.getInterfaces();
723         if (MapUtils.isNotEmpty(serviceInterfaces)) {
724             serviceInterfaces.forEach(resourceInstance::addInterface);
725         }
726         resourceInstance.setProperties(PropertiesUtils.getProperties(service));
727         resourceInstance.setAttributes(service.getAttributes());
728         final List<InputDefinition> serviceInputs = service.getInputs();
729         resourceInstance.setInputs(serviceInputs);
730         resourceInstance.setSourceModelInvariant(service.getInvariantUUID());
731         resourceInstance.setSourceModelName(service.getName());
732         resourceInstance.setSourceModelUuid(service.getUUID());
733         resourceInstance.setSourceModelUid(service.getUniqueId());
734         resourceInstance.setComponentUid(origComponent.getUniqueId());
735         resourceInstance.setComponentVersion(service.getVersion());
736         switch (resourceInstance.getOriginType()) {
737             case ServiceProxy:
738                 return fillProxyInstanceData(resourceInstance, origComponent, service);
739             case ServiceSubstitution:
740                 return fillServiceSubstitutableNodeTypeData(resourceInstance, service);
741             default:
742                 return StorageOperationStatus.OK;
743         }
744     }
745
746     private StorageOperationStatus fillProxyInstanceData(final ComponentInstance resourceInstance, final Component origComponent,
747                                                          final Component service) {
748         final String name = ValidationUtils.normalizeComponentInstanceName(service.getName()) + ToscaOperationFacade.PROXY_SUFFIX;
749         final String toscaResourceName = ((Resource) origComponent).getToscaResourceName();
750         final int lastIndexOf = toscaResourceName.lastIndexOf('.');
751         if (lastIndexOf != -1) {
752             final String proxyToscaName = toscaResourceName.substring(0, lastIndexOf + 1) + name;
753             resourceInstance.setToscaComponentName(proxyToscaName);
754         }
755         resourceInstance.setName(name);
756         resourceInstance.setIsProxy(true);
757         resourceInstance.setDescription("A Proxy for Service " + service.getName());
758         return StorageOperationStatus.OK;
759     }
760
761     private StorageOperationStatus fillServiceSubstitutableNodeTypeData(final ComponentInstance resourceInstance, final Component service) {
762         resourceInstance.setToscaComponentName("org.openecomp.service." + ValidationUtils.convertToSystemName(service.getName()));
763         resourceInstance.setName(ValidationUtils.normalizeComponentInstanceName(service.getName()));
764         resourceInstance.setIsProxy(false);
765         resourceInstance.setDescription("A substitutable node type for service " + service.getName());
766         return StorageOperationStatus.OK;
767     }
768
769     public Either<CreateAndAssotiateInfo, ResponseFormat> createAndAssociateRIToRI(String containerComponentParam, String containerComponentId,
770                                                                                    String userId, CreateAndAssotiateInfo createAndAssotiateInfo) {
771         Either<CreateAndAssotiateInfo, ResponseFormat> resultOp = null;
772         ComponentInstance resourceInstance = createAndAssotiateInfo.getNode();
773         RequirementCapabilityRelDef associationInfo = createAndAssotiateInfo.getAssociate();
774         User user = validateUserExists(userId);
775         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
776         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
777         if (ModelConverter.isAtomicComponent(containerComponent)) {
778             log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType());
779             return Either
780                 .right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType()));
781         }
782         validateCanWorkOnComponent(containerComponent, userId);
783         boolean failed = false;
784         try {
785             lockComponent(containerComponent, "createAndAssociateRIToRI");
786             log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH);
787             Component origComponent = getOriginComponentFromComponentInstance(resourceInstance);
788             log.debug(ENTITY_ON_GRAPH_IS_CREATED);
789             ComponentInstance resResourceInfo = createComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, user);
790             if (associationInfo.getFromNode() == null || associationInfo.getFromNode().isEmpty()) {
791                 associationInfo.setFromNode(resResourceInfo.getUniqueId());
792             } else {
793                 associationInfo.setToNode(resResourceInfo.getUniqueId());
794             }
795             Either<RequirementCapabilityRelDef, StorageOperationStatus> resultReqCapDef = toscaOperationFacade
796                 .associateResourceInstances(containerComponent, containerComponentId, associationInfo);
797             if (resultReqCapDef.isLeft()) {
798                 log.debug(ENTITY_ON_GRAPH_IS_CREATED);
799                 RequirementCapabilityRelDef resReqCapabilityRelDef = resultReqCapDef.left().value();
800                 CreateAndAssotiateInfo resInfo = new CreateAndAssotiateInfo(resResourceInfo, resReqCapabilityRelDef);
801                 resultOp = Either.left(resInfo);
802                 return resultOp;
803             } else {
804                 log.info("Failed to associate node {} with node {}", associationInfo.getFromNode(), associationInfo.getToNode());
805                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstance(
806                     componentsUtils.convertFromStorageResponseForResourceInstance(resultReqCapDef.right().value(), true), "", null));
807                 return resultOp;
808             }
809         } catch (ComponentException e) {
810             failed = true;
811             throw e;
812         } finally {
813             unlockComponent(failed, containerComponent);
814         }
815     }
816
817     private Component getOriginComponentFromComponentInstance(ComponentInstance componentInstance) {
818         return getOriginComponentFromComponentInstance(componentInstance.getName(), componentInstance.getComponentUid());
819     }
820
821     private Component getInstanceOriginNode(ComponentInstance componentInstance) {
822         return getOriginComponentFromComponentInstance(componentInstance.getName(), componentInstance.getActualComponentUid());
823     }
824
825     private Component getOriginComponentFromComponentInstance(String componentInstanceName, String origComponetId) {
826         Either<Component, StorageOperationStatus> eitherComponent = toscaOperationFacade.getToscaFullElement(origComponetId);
827         if (eitherComponent.isRight()) {
828             log.debug("Failed to get origin component with id {} for component instance {} ", origComponetId, componentInstanceName);
829             throw new ByActionStatusComponentException(
830                 componentsUtils.convertFromStorageResponse(eitherComponent.right().value(), ComponentTypeEnum.RESOURCE), "", null);
831         }
832         return eitherComponent.left().value();
833     }
834
835     private ComponentInstance createComponentInstanceOnGraph(org.openecomp.sdc.be.model.Component containerComponent, Component originComponent,
836                                                              ComponentInstance componentInstance, User user) {
837         Either<ImmutablePair<Component, String>, StorageOperationStatus> result = toscaOperationFacade
838             .addComponentInstanceToTopologyTemplate(containerComponent, originComponent, componentInstance, false, user);
839         if (result.isRight()) {
840             log.debug(FAILED_TO_CREATE_ENTRY_ON_GRAPH_FOR_COMPONENT_INSTANCE, componentInstance.getName());
841             throw new ByResponseFormatComponentException(componentsUtils
842                 .getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), "",
843                     null));
844         }
845         log.debug(ENTITY_ON_GRAPH_IS_CREATED);
846         Component updatedComponent = result.left().value().getLeft();
847         Map<String, String> existingEnvVersions = new HashMap<>();
848         // TODO existingEnvVersions ??
849         addComponentInstanceArtifacts(updatedComponent, componentInstance, originComponent, user, existingEnvVersions);
850         Optional<ComponentInstance> updatedInstanceOptional = updatedComponent.getComponentInstances().stream()
851             .filter(ci -> ci.getUniqueId().equals(result.left().value().getRight())).findFirst();
852         if (!updatedInstanceOptional.isPresent()) {
853             log.debug("Failed to fetch new added component instance {} from component {}", componentInstance.getName(), containerComponent.getName());
854             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName());
855         }
856         return updatedInstanceOptional.get();
857     }
858
859     public boolean isCloudSpecificArtifact(String artifact) {
860         if (artifact.contains(CLOUD_SPECIFIC_FIXED_KEY_WORD)) {
861             for (int i = 0; i < CLOUD_SPECIFIC_KEY_WORDS.length; i++) {
862                 if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(artifact::contains)) {
863                     return false;
864                 }
865             }
866             return true;
867         } else {
868             return false;
869         }
870     }
871
872     /**
873      * addResourceInstanceArtifacts - add artifacts (HEAT_ENV) to resource instance The instance artifacts are generated from the resource's
874      * artifacts
875      *
876      * @param containerComponent
877      * @param componentInstance
878      * @param originComponent
879      * @param user
880      * @param existingEnvVersions
881      * @return
882      */
883     protected ActionStatus addComponentInstanceArtifacts(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance componentInstance,
884                                                          org.openecomp.sdc.be.model.Component originComponent, User user,
885                                                          Map<String, String> existingEnvVersions) {
886         log.debug("add artifacts to resource instance");
887         List<GroupDefinition> filteredGroups = new ArrayList<>();
888         ActionStatus status = setResourceArtifactsOnResourceInstance(componentInstance);
889         if (ActionStatus.OK != status) {
890             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(status, "", null));
891         }
892         StorageOperationStatus artStatus;
893         // generate heat_env if necessary
894         Map<String, ArtifactDefinition> componentDeploymentArtifacts = componentInstance.getDeploymentArtifacts();
895         if (MapUtils.isNotEmpty(componentDeploymentArtifacts)) {
896             Map<String, ArtifactDefinition> finalDeploymentArtifacts = new HashMap<>();
897             Map<String, List<ArtifactDefinition>> groupInstancesArtifacts = new HashMap<>();
898             Integer defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout()
899                 .getDefaultMinutes();
900             List<ArtifactDefinition> listOfCloudSpecificArts = new ArrayList<>();
901             for (ArtifactDefinition artifact : componentDeploymentArtifacts.values()) {
902                 String type = artifact.getArtifactType();
903                 if (!type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())) {
904                     finalDeploymentArtifacts.put(artifact.getArtifactLabel(), artifact);
905                 }
906                 if (type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HELM.getType()) || type
907                     .equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()) || type
908                     .equalsIgnoreCase(ArtifactTypeEnum.CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT.getType())) {
909                     artifact.setTimeout(defaultHeatTimeout);
910                 } else {
911                     continue;
912                 }
913                 if (artifact.checkEsIdExist()) {
914                     ArtifactDefinition artifactDefinition = artifactBusinessLogic
915                         .createHeatEnvPlaceHolder(new ArrayList<>(), artifact, ArtifactsBusinessLogic.HEAT_ENV_NAME, componentInstance.getUniqueId(),
916                             NodeTypeEnum.ResourceInstance, componentInstance.getName(), user, containerComponent, existingEnvVersions);
917                     // put env
918                     finalDeploymentArtifacts.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
919                     if (CollectionUtils.isNotEmpty(originComponent.getGroups())) {
920                         filteredGroups = originComponent.getGroups().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
921                     }
922                     if (isCloudSpecificArtifact(artifactDefinition.getArtifactName())) {
923                         listOfCloudSpecificArts.add(artifact);
924                     }
925                     if (CollectionUtils.isNotEmpty(filteredGroups)) {
926                         filteredGroups.stream()
927                             .filter(g -> g.getArtifacts() != null && g.getArtifacts().stream().anyMatch(p -> p.equals(artifactDefinition.getGeneratedFromId()))).findFirst()
928                             .ifPresent(g -> fillInstanceArtifactMap(groupInstancesArtifacts, artifactDefinition, g));
929                     }
930                 }
931             }
932             groupInstancesArtifacts.forEach((k, v) -> v.addAll(listOfCloudSpecificArts));
933             filteredGroups.forEach(g -> listOfCloudSpecificArts.forEach(e -> {
934                 g.getArtifactsUuid().add(e.getArtifactUUID());
935                 g.getArtifacts().add(e.getUniqueId());
936             }));
937             artStatus = toscaOperationFacade
938                 .addDeploymentArtifactsToInstance(containerComponent.getUniqueId(), componentInstance, finalDeploymentArtifacts);
939             if (artStatus != StorageOperationStatus.OK) {
940                 log.debug("Failed to add instance deployment artifacts for instance {} in conatiner {} error {}", componentInstance.getUniqueId(),
941                     containerComponent.getUniqueId(), artStatus);
942                 throw new ByResponseFormatComponentException(
943                     componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForResourceInstance(artStatus, false)));
944             }
945             StorageOperationStatus result = toscaOperationFacade
946                 .addGroupInstancesToComponentInstance(containerComponent, componentInstance, filteredGroups, groupInstancesArtifacts);
947             if (result != StorageOperationStatus.OK) {
948                 log.debug("failed to update group instance for component instance {}", componentInstance.getUniqueId());
949                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result)));
950             }
951             componentInstance.setDeploymentArtifacts(finalDeploymentArtifacts);
952         }
953         artStatus = toscaOperationFacade
954             .addInformationalArtifactsToInstance(containerComponent.getUniqueId(), componentInstance, originComponent.getArtifacts());
955         if (artStatus != StorageOperationStatus.OK) {
956             log.debug("Failed to add informational artifacts to the instance {} belonging to the conatiner {}. Status is {}",
957                 componentInstance.getUniqueId(), containerComponent.getUniqueId(), artStatus);
958             throw new ByResponseFormatComponentException(
959                 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForResourceInstance(artStatus, false)));
960         }
961         componentInstance.setArtifacts(originComponent.getArtifacts());
962         return ActionStatus.OK;
963     }
964
965     private void fillInstanceArtifactMap(Map<String, List<ArtifactDefinition>> groupInstancesArtifacts, ArtifactDefinition artifactDefinition,
966                                          GroupDefinition groupInstance) {
967         List<ArtifactDefinition> artifactsUid;
968         if (groupInstancesArtifacts.containsKey(groupInstance.getUniqueId())) {
969             artifactsUid = groupInstancesArtifacts.get(groupInstance.getUniqueId());
970         } else {
971             artifactsUid = new ArrayList<>();
972         }
973         artifactsUid.add(artifactDefinition);
974         groupInstancesArtifacts.put(groupInstance.getUniqueId(), artifactsUid);
975     }
976
977     private ActionStatus setResourceArtifactsOnResourceInstance(ComponentInstance resourceInstance) {
978         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getResourceDeploymentArtifacts = artifactBusinessLogic
979             .getArtifacts(resourceInstance.getComponentUid(), NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null);
980         Map<String, ArtifactDefinition> deploymentArtifacts = new HashMap<>();
981         if (getResourceDeploymentArtifacts.isRight()) {
982             StorageOperationStatus status = getResourceDeploymentArtifacts.right().value();
983             if (status != StorageOperationStatus.NOT_FOUND) {
984                 log.debug("Failed to fetch resource: {} artifacts. status is {}", resourceInstance.getComponentUid(), status);
985                 return componentsUtils.convertFromStorageResponseForResourceInstance(status, true);
986             }
987         } else {
988             deploymentArtifacts = getResourceDeploymentArtifacts.left().value();
989         }
990         if (!deploymentArtifacts.isEmpty()) {
991             Map<String, ArtifactDefinition> tempDeploymentArtifacts = new HashMap<>(deploymentArtifacts);
992             for (Entry<String, ArtifactDefinition> artifact : deploymentArtifacts.entrySet()) {
993                 if (!artifact.getValue().checkEsIdExist()) {
994                     tempDeploymentArtifacts.remove(artifact.getKey());
995                 }
996             }
997             resourceInstance.setDeploymentArtifacts(tempDeploymentArtifacts);
998         }
999         return ActionStatus.OK;
1000     }
1001
1002     public Either<ComponentInstance, ResponseFormat> updateComponentInstanceMetadata(String containerComponentParam, String containerComponentId,
1003                                                                                      String componentInstanceId, String userId,
1004                                                                                      ComponentInstance componentInstance) {
1005         return updateComponentInstanceMetadata(containerComponentParam, containerComponentId, componentInstanceId, userId, componentInstance, true);
1006     }
1007
1008     public Either<ComponentInstance, ResponseFormat> updateComponentInstanceMetadata(final String containerComponentParam,
1009                                                                                      final String containerComponentId,
1010                                                                                      final String componentInstanceId, final String userId,
1011                                                                                      ComponentInstance componentInstance, boolean needLock) {
1012         validateUserExists(userId);
1013         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
1014         final Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
1015         validateCanWorkOnComponent(containerComponent, userId);
1016         ComponentTypeEnum instanceType = getComponentType(containerComponentType);
1017         Either<Boolean, StorageOperationStatus> validateParentStatus = toscaOperationFacade
1018             .validateComponentExists(componentInstance.getComponentUid());
1019         if (validateParentStatus.isRight()) {
1020             log.debug("Failed to get component instance {} on service {}", componentInstanceId, containerComponentId);
1021             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, componentInstance.getName(),
1022                 instanceType.getValue().toLowerCase());
1023         }
1024         if (!Boolean.TRUE.equals(validateParentStatus.left().value())) {
1025             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(),
1026                 instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), containerComponentId);
1027         }
1028         if (needLock) {
1029             lockComponent(containerComponent, "updateComponentInstance");
1030         }
1031         Component origComponent;
1032         boolean failed = false;
1033         try {
1034             origComponent = getOriginComponentFromComponentInstance(componentInstance);
1035             componentInstance = updateComponentInstanceMetadata(containerComponent, containerComponentType, origComponent, componentInstanceId,
1036                 componentInstance);
1037         } catch (ComponentException e) {
1038             failed = true;
1039             throw e;
1040         } finally {
1041             if (needLock) {
1042                 unlockComponent(failed, containerComponent);
1043             }
1044         }
1045         return Either.left(componentInstance);
1046     }
1047
1048     // New Multiple Instance Update API
1049     public List<ComponentInstance> updateComponentInstance(String containerComponentParam, Component containerComponent, String containerComponentId,
1050                                                            String userId, List<ComponentInstance> componentInstanceList, boolean needLock) {
1051         boolean failed = false;
1052         try {
1053             validateUserExists(userId);
1054             final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
1055             ComponentParametersView componentFilter = new ComponentParametersView();
1056             componentFilter.disableAll();
1057             componentFilter.setIgnoreUsers(false);
1058             componentFilter.setIgnoreComponentInstances(false);
1059             if (containerComponent == null) {
1060                 containerComponent = validateComponentExistsByFilter(containerComponentId, containerComponentType, componentFilter);
1061             }
1062             validateCanWorkOnComponent(containerComponent, userId);
1063             ComponentTypeEnum instanceType = getComponentType(containerComponentType);
1064             for (ComponentInstance componentInstance : componentInstanceList) {
1065                 boolean validateParent = validateParent(containerComponent, componentInstance.getUniqueId());
1066                 if (!validateParent) {
1067                     throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(),
1068                         instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), containerComponentId);
1069                 }
1070             }
1071             if (needLock) {
1072                 lockComponent(containerComponent, "updateComponentInstance");
1073             }
1074             List<ComponentInstance> updatedList = new ArrayList<>();
1075             List<ComponentInstance> instancesFromContainerComponent = containerComponent.getComponentInstances();
1076             List<ComponentInstance> listForUpdate = new ArrayList<>();
1077             if (instancesFromContainerComponent == null || instancesFromContainerComponent.isEmpty()) {
1078                 containerComponent.setComponentInstances(componentInstanceList);
1079             } else {
1080                 Iterator<ComponentInstance> iterator = instancesFromContainerComponent.iterator();
1081                 while (iterator.hasNext()) {
1082                     ComponentInstance origInst = iterator.next();
1083                     Optional<ComponentInstance> op = componentInstanceList.stream().filter(ci -> ci.getUniqueId().equals(origInst.getUniqueId()))
1084                         .findAny();
1085                     if (op.isPresent()) {
1086                         ComponentInstance updatedCi = op.get();
1087                         updatedCi = buildComponentInstance(updatedCi, origInst);
1088                         Boolean isUniqueName = validateInstanceNameUniquenessUponUpdate(containerComponent, origInst, updatedCi.getName());
1089                         if (!Boolean.TRUE.equals(isUniqueName)) {
1090                             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1091                                 "Failed to update the name of the component instance {} to {}. A component instance with the same name already exists. ",
1092                                 origInst.getName(), updatedCi.getName());
1093                             throw new ByResponseFormatComponentException(componentsUtils
1094                                 .getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, containerComponentType.getValue(), origInst.getName()));
1095                         }
1096                         listForUpdate.add(updatedCi);
1097                     } else {
1098                         listForUpdate.add(origInst);
1099                     }
1100                 }
1101                 containerComponent.setComponentInstances(listForUpdate);
1102                 Either<Component, StorageOperationStatus> updateStatus = toscaOperationFacade
1103                     .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, componentFilter);
1104                 if (updateStatus.isRight()) {
1105                     CommonUtility
1106                         .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update metadata belonging to container component {}. Status is {}. ",
1107                             containerComponent.getName(), updateStatus.right().value());
1108                     throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
1109                         componentsUtils.convertFromStorageResponseForResourceInstance(updateStatus.right().value(), true), "", null));
1110                 }
1111                 for (ComponentInstance updatedInstance : updateStatus.left().value().getComponentInstances()) {
1112                     Optional<ComponentInstance> op = componentInstanceList.stream().filter(ci -> ci.getName().equals(updatedInstance.getName()))
1113                         .findAny();
1114                     if (op.isPresent()) {
1115                         updatedList.add(updatedInstance);
1116                     }
1117                 }
1118             }
1119             return updatedList;
1120         } catch (ComponentException e) {
1121             failed = true;
1122             throw e;
1123         } finally {
1124             if (needLock) {
1125                 unlockComponent(failed, containerComponent);
1126             }
1127         }
1128     }
1129
1130     private boolean validateParent(org.openecomp.sdc.be.model.Component containerComponent, String nodeTemplateId) {
1131         return containerComponent.getComponentInstances().stream().anyMatch(p -> p.getUniqueId().equals(nodeTemplateId));
1132     }
1133
1134     private ComponentTypeEnum getComponentType(ComponentTypeEnum containerComponentType) {
1135         if (ComponentTypeEnum.PRODUCT == containerComponentType) {
1136             return ComponentTypeEnum.SERVICE_INSTANCE;
1137         } else {
1138             return ComponentTypeEnum.RESOURCE_INSTANCE;
1139         }
1140     }
1141
1142     private ComponentInstance updateComponentInstanceMetadata(Component containerComponent, ComponentTypeEnum containerComponentType,
1143                                                               org.openecomp.sdc.be.model.Component origComponent, String componentInstanceId,
1144                                                               ComponentInstance componentInstance) {
1145         Optional<ComponentInstance> componentInstanceOptional;
1146         Either<ImmutablePair<Component, String>, StorageOperationStatus> updateRes = null;
1147         ComponentInstance oldComponentInstance = null;
1148         boolean isNameChanged = false;
1149         componentInstanceOptional = containerComponent.getComponentInstances().stream()
1150             .filter(ci -> ci.getUniqueId().equals(componentInstance.getUniqueId())).findFirst();
1151         if (!componentInstanceOptional.isPresent()) {
1152             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find the component instance {} in container component {}. ",
1153                 componentInstance.getName(), containerComponent.getName());
1154             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName());
1155         }
1156         String oldComponentName;
1157         oldComponentInstance = componentInstanceOptional.get();
1158         oldComponentName = oldComponentInstance.getName();
1159         String newInstanceName = componentInstance.getName();
1160         if (oldComponentName != null && !oldComponentInstance.getName().equals(newInstanceName)) {
1161             isNameChanged = true;
1162         }
1163         Boolean isUniqueName = validateInstanceNameUniquenessUponUpdate(containerComponent, oldComponentInstance, newInstanceName);
1164         if (!Boolean.TRUE.equals(isUniqueName)) {
1165             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1166                 "Failed to update the name of the component instance {} to {}. A component instance with the same name already exists. ",
1167                 oldComponentInstance.getName(), newInstanceName);
1168             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, containerComponentType.getValue(),
1169                 componentInstance.getName());
1170         }
1171         if (!DirectivesUtil.isValid(componentInstance.getDirectives())) {
1172             final String directivesStr = componentInstance.getDirectives().stream().collect(Collectors.joining(" , ", " [ ", " ] "));
1173             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1174                 "Failed to update the directives of the component instance {} to {}. Directives data {} is invalid. ", oldComponentInstance.getName(),
1175                 newInstanceName, directivesStr);
1176             throw new ByActionStatusComponentException(ActionStatus.DIRECTIVES_INVALID_VALUE, containerComponentType.getValue(),
1177                 componentInstance.getName());
1178         }
1179         updateRes = toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, origComponent,
1180             updateComponentInstanceMetadata(oldComponentInstance, componentInstance));
1181         if (updateRes.isRight()) {
1182             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1183                 "Failed to update metadata of component instance {} belonging to container component {}. Status is {}. ", componentInstance.getName(),
1184                 containerComponent.getName(), updateRes.right().value());
1185             throw new ByResponseFormatComponentException(componentsUtils
1186                 .getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(updateRes.right().value(), true),
1187                     "", null));
1188         } else {
1189             // region - Update instance Groups
1190             if (isNameChanged) {
1191                 Either<StorageOperationStatus, StorageOperationStatus> result = toscaOperationFacade
1192                     .cleanAndAddGroupInstancesToComponentInstance(containerComponent, oldComponentInstance, componentInstanceId);
1193                 if (result.isRight()) {
1194                     CommonUtility
1195                         .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to rename group instances for container {}. error {} ", componentInstanceId,
1196                             result.right().value());
1197                 }
1198                 if (containerComponent instanceof Service) {
1199                     Either<ComponentInstance, ResponseFormat> renameEither = renameServiceFilter((Service) containerComponent, newInstanceName,
1200                         oldComponentInstance.getName());
1201                     if (renameEither.isRight()) {
1202                         throw new ByResponseFormatComponentException(renameEither.right().value());
1203                     }
1204                     updateForwardingPathDefinition(containerComponent, componentInstance, oldComponentName);
1205                 }
1206             }
1207             // endregion
1208         }
1209         String newInstanceId = updateRes.left().value().getRight();
1210         Optional<ComponentInstance> updatedInstanceOptional = updateRes.left().value().getLeft().getComponentInstances().stream()
1211             .filter(ci -> ci.getUniqueId().equals(newInstanceId)).findFirst();
1212         if (!updatedInstanceOptional.isPresent()) {
1213             log.debug("Failed to update metadata of component instance {} of container component {}", componentInstance.getName(),
1214                 containerComponent.getName());
1215             throw new ByResponseFormatComponentException(
1216                 componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName()));
1217         }
1218         return componentInstanceOptional.get();
1219     }
1220
1221     private void updateForwardingPathDefinition(Component containerComponent, ComponentInstance componentInstance, String oldComponentName) {
1222         Collection<ForwardingPathDataDefinition> forwardingPathDataDefinitions = getForwardingPathDataDefinitions(containerComponent.getUniqueId());
1223         Set<ForwardingPathDataDefinition> updated = new ForwardingPathUtils()
1224             .updateComponentInstanceName(forwardingPathDataDefinitions, oldComponentName, componentInstance.getName());
1225         updated.forEach(fp -> {
1226             Either<ForwardingPathDataDefinition, StorageOperationStatus> resultEither = forwardingPathOperation
1227                 .updateForwardingPath(containerComponent.getUniqueId(), fp);
1228             if (resultEither.isRight()) {
1229                 CommonUtility.addRecordToLog(log, LogLevelEnum.ERROR, "Failed to rename forwarding path for container {}. error {} ",
1230                     containerComponent.getName(), resultEither.right().value());
1231             }
1232         });
1233     }
1234
1235     public Either<ComponentInstance, ResponseFormat> renameServiceFilter(final Service containerComponent, final String newInstanceName,
1236                                                                          final String oldInstanceName) {
1237         Map<String, CINodeFilterDataDefinition> renamedNodesFilter = ServiceFilterUtils
1238             .getRenamedNodesFilter(containerComponent, oldInstanceName, newInstanceName);
1239         for (Entry<String, CINodeFilterDataDefinition> entry : renamedNodesFilter.entrySet()) {
1240             Either<CINodeFilterDataDefinition, StorageOperationStatus> renameEither = nodeFilterOperation
1241                 .updateNodeFilter(containerComponent.getUniqueId(), entry.getKey(), entry.getValue());
1242             if (renameEither.isRight()) {
1243                 return Either.right(componentsUtils.getResponseFormatForResourceInstance(
1244                     componentsUtils.convertFromStorageResponse(renameEither.right().value(), ComponentTypeEnum.SERVICE), containerComponent.getName(),
1245                     null));
1246             }
1247         }
1248         return Either.left(null);
1249     }
1250
1251     /**
1252      * @param oldPrefix-                  The normalized old vf name
1253      * @param newNormailzedPrefix-        The normalized new vf name
1254      * @param qualifiedGroupInstanceName- old Group Instance Name
1255      **/
1256
1257     // modify group names
1258     private String getNewGroupName(String oldPrefix, String newNormailzedPrefix, String qualifiedGroupInstanceName) {
1259         if (qualifiedGroupInstanceName == null) {
1260             log.info("CANNOT change group name ");
1261             return null;
1262         }
1263         if (qualifiedGroupInstanceName.startsWith(oldPrefix) || qualifiedGroupInstanceName
1264             .startsWith(ValidationUtils.normalizeComponentInstanceName(oldPrefix))) {
1265             return qualifiedGroupInstanceName.replaceFirst(oldPrefix, newNormailzedPrefix);
1266         }
1267         return qualifiedGroupInstanceName;
1268     }
1269
1270     private ComponentInstance updateComponentInstanceMetadata(ComponentInstance oldComponentInstance, ComponentInstance newComponentInstance) {
1271         oldComponentInstance.setName(newComponentInstance.getName());
1272         oldComponentInstance.setModificationTime(System.currentTimeMillis());
1273         oldComponentInstance.setCustomizationUUID(UUID.randomUUID().toString());
1274         oldComponentInstance.setDirectives(newComponentInstance.getDirectives());
1275         oldComponentInstance.setMaxOccurrences(newComponentInstance.getMaxOccurrences());
1276         oldComponentInstance.setMinOccurrences(newComponentInstance.getMinOccurrences());
1277         oldComponentInstance.setInstanceCount(newComponentInstance.getInstanceCount());
1278         if (oldComponentInstance.getGroupInstances() != null) {
1279             oldComponentInstance.getGroupInstances().forEach(group -> group.setName(getNewGroupName(oldComponentInstance.getNormalizedName(),
1280                 ValidationUtils.normalizeComponentInstanceName(newComponentInstance.getName()), group.getName())));
1281         }
1282         return oldComponentInstance;
1283     }
1284
1285     public ComponentInstance deleteComponentInstance(final String containerComponentParam, final String containerComponentId,
1286                                                      final String componentInstanceId, String userId) throws BusinessLogicException {
1287         validateUserExists(userId);
1288         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
1289         final Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
1290         validateCanWorkOnComponent(containerComponent, userId);
1291         boolean failed = false;
1292         final Optional<ComponentInstance> componentInstanceOptional = containerComponent.getComponentInstanceById(componentInstanceId);
1293         if (!componentInstanceOptional.isPresent()) {
1294             throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND));
1295         }
1296         ComponentInstance componentInstance = componentInstanceOptional.get();
1297         try {
1298             if (containerComponent instanceof Service || containerComponent instanceof Resource) {
1299                 final Either<String, StorageOperationStatus> deleteServiceFilterEither = nodeFilterOperation
1300                     .deleteNodeFilter(containerComponent, componentInstanceId);
1301                 if (deleteServiceFilterEither.isRight()) {
1302                     final ActionStatus status = componentsUtils
1303                         .convertFromStorageResponse(deleteServiceFilterEither.right().value(), containerComponentType);
1304                     janusGraphDao.rollback();
1305                     throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(status, componentInstanceId));
1306                 }
1307                 final Either<ComponentInstance, ResponseFormat> resultOp = deleteNodeFiltersFromComponentInstance(containerComponent,
1308                     componentInstance, containerComponentType, userId);
1309                 if (resultOp.isRight()) {
1310                     janusGraphDao.rollback();
1311                     throw new ByResponseFormatComponentException(resultOp.right().value());
1312                 }
1313             }
1314             lockComponent(containerComponent, "deleteComponentInstance");
1315             final ComponentInstance deletedCompInstance = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentType);
1316             componentInstance = deleteForwardingPathsRelatedTobeDeletedComponentInstance(containerComponentId, containerComponentType,
1317                 deletedCompInstance);
1318             final ActionStatus onDeleteOperationsStatus = onChangeInstanceOperationOrchestrator
1319                 .doOnDeleteInstanceOperations(containerComponent, componentInstanceId);
1320             if (ActionStatus.OK != onDeleteOperationsStatus) {
1321                 throw new ByActionStatusComponentException(onDeleteOperationsStatus);
1322             }
1323         } catch (final ComponentException e) {
1324             failed = true;
1325             throw e;
1326         } finally {
1327             unlockComponent(failed, containerComponent);
1328         }
1329         return componentInstance;
1330     }
1331
1332     /**
1333      * Try to modify the delete and return two cases
1334      *
1335      * @param containerComponentParam
1336      * @param containerComponentId
1337      * @param componentInstanceId
1338      * @param userId
1339      * @return
1340      */
1341     public Either<ComponentInstance, ResponseFormat> deleteAbstractComponentInstance(String containerComponentParam, String containerComponentId,
1342                                                                                      String componentInstanceId, String userId) {
1343         log.debug("enter deleteAbstractComponentInstance");
1344         validateUserExists(userId);
1345         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
1346         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null);
1347         validateCanWorkOnComponent(containerComponent, userId);
1348         boolean failed = false;
1349         ComponentInstance deletedRelatedInst;
1350         try {
1351             if (containerComponent instanceof Service) {
1352                 final Optional<ComponentInstance> componentInstanceById = containerComponent.getComponentInstanceById(componentInstanceId);
1353                 if (componentInstanceById.isPresent()) {
1354                     ComponentInstance componentInstance = componentInstanceById.get();
1355                     Either<String, StorageOperationStatus> deleteServiceFilterEither = nodeFilterOperation
1356                         .deleteNodeFilter(containerComponent, componentInstanceId);
1357                     if (deleteServiceFilterEither.isRight()) {
1358                         log.debug("enter deleteAbstractComponentInstance:deleteServiceFilterEither is right, filed");
1359                         ActionStatus status = componentsUtils
1360                             .convertFromStorageResponse(deleteServiceFilterEither.right().value(), containerComponentType);
1361                         janusGraphDao.rollback();
1362                         return Either.right(componentsUtils.getResponseFormat(status, componentInstance.getName()));
1363                     }
1364                     Either<ComponentInstance, ResponseFormat> resultOp = deleteNodeFiltersFromComponentInstance(containerComponent, componentInstance,
1365                         ComponentTypeEnum.SERVICE, userId);
1366                     if (resultOp.isRight()) {
1367                         log.debug("enter deleteAbstractComponentInstance:resultOp is right, filed");
1368                         janusGraphDao.rollback();
1369                         return resultOp;
1370                     }
1371                 }
1372             }
1373             log.debug("enter deleteAbstractComponentInstance:");
1374             lockComponent(containerComponent, "deleteComponentInstance");
1375             ComponentInstance deletedCompInstance = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentType);
1376             deletedRelatedInst = deleteForwardingPathsRelatedTobeDeletedComponentInstance(containerComponentId, containerComponentType,
1377                 deletedCompInstance);
1378             ActionStatus onDeleteOperationsStatus = onChangeInstanceOperationOrchestrator
1379                 .doOnDeleteInstanceOperations(containerComponent, componentInstanceId);
1380             log.debug("enter deleteAbstractComponentInstance,get onDeleteOperationsStatus:{}", onDeleteOperationsStatus);
1381             if (ActionStatus.OK != onDeleteOperationsStatus) {
1382                 throw new ByActionStatusComponentException(onDeleteOperationsStatus);
1383             }
1384         } catch (ComponentException e) {
1385             failed = true;
1386             throw e;
1387         } finally {
1388             unlockComponent(failed, containerComponent);
1389         }
1390         log.debug("enter deleteAbstractComponentInstance,deleted RelatedInst success");
1391         return Either.left(deletedRelatedInst);
1392     }
1393
1394     public Either<ComponentInstance, ResponseFormat> deleteNodeFiltersFromComponentInstance(final Component component,
1395                                                                                             final ComponentInstance componentInstance,
1396                                                                                             final ComponentTypeEnum containerComponentType,
1397                                                                                             final String userId) {
1398         final Set<String> componentFiltersIDsToBeDeleted = getComponentFiltersRelatedToComponentInstance(component.getUniqueId(), componentInstance);
1399         if (!componentFiltersIDsToBeDeleted.isEmpty()) {
1400             final Set<String> ids = component.getComponentInstances().stream().filter(ci -> componentFiltersIDsToBeDeleted.contains(ci.getName()))
1401                 .map(ComponentInstance::getUniqueId).collect(Collectors.toSet());
1402             final Either<Set<String>, StorageOperationStatus> deleteComponentNodeFiltersEither = nodeFilterOperation
1403                 .deleteNodeFilters(component, ids);
1404             if (deleteComponentNodeFiltersEither.isRight()) {
1405                 final ActionStatus status = componentsUtils
1406                     .convertFromStorageResponse(deleteComponentNodeFiltersEither.right().value(), containerComponentType);
1407                 return Either.right(componentsUtils.getResponseFormat(status, componentInstance.getName()));
1408             }
1409             for (final String id : ids) {
1410                 final Optional<ComponentInstance> componentInstanceById = component.getComponentInstanceById(id);
1411                 if (!componentInstanceById.isPresent()) {
1412                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1413                 }
1414                 final ComponentInstance componentInstanceToBeUpdated = componentInstanceById.get();
1415                 componentInstanceToBeUpdated.setDirectives(Collections.emptyList());
1416                 final Either<ComponentInstance, ResponseFormat> componentInstanceResponseFormatEither = updateComponentInstanceMetadata(
1417                     containerComponentType.getValue(), component.getUniqueId(), componentInstanceToBeUpdated.getUniqueId(), userId,
1418                     componentInstanceToBeUpdated, false);
1419                 if (componentInstanceResponseFormatEither.isRight()) {
1420                     return componentInstanceResponseFormatEither;
1421                 }
1422             }
1423         }
1424         return Either.left(componentInstance);
1425     }
1426
1427     private Set<String> getComponentFiltersRelatedToComponentInstance(String containerComponentId, ComponentInstance componentInstance) {
1428         ComponentParametersView filter = new ComponentParametersView(true);
1429         filter.setIgnoreComponentInstances(false);
1430         Either<Component, StorageOperationStatus> componentFilterOrigin = toscaOperationFacade.getToscaElement(containerComponentId, filter);
1431         final Component component = componentFilterOrigin.left().value();
1432         return ComponentsUtils.getNodesFiltersToBeDeleted(component, componentInstance);
1433     }
1434
1435     ComponentInstance deleteForwardingPathsRelatedTobeDeletedComponentInstance(String containerComponentId, ComponentTypeEnum containerComponentType,
1436                                                                                ComponentInstance componentInstance) {
1437         if (containerComponentType == ComponentTypeEnum.SERVICE) {
1438             List<String> pathIDsToBeDeleted = getForwardingPathsRelatedToComponentInstance(containerComponentId, componentInstance.getName());
1439             if (!pathIDsToBeDeleted.isEmpty()) {
1440                 deleteForwardingPaths(containerComponentId, pathIDsToBeDeleted);
1441             }
1442         }
1443         return componentInstance;
1444     }
1445
1446     private void deleteForwardingPaths(String serviceId, List<String> pathIdsToDelete) {
1447         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1448         if (storageStatus.isRight()) {
1449             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus.right().value()));
1450         }
1451         Either<Set<String>, StorageOperationStatus> result = forwardingPathOperation
1452             .deleteForwardingPath(storageStatus.left().value(), Sets.newHashSet(pathIdsToDelete));
1453         if (result.isRight()) {
1454             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(result.right().value()));
1455         }
1456     }
1457
1458     private List<String> getForwardingPathsRelatedToComponentInstance(String containerComponentId, String componentInstanceId) {
1459         Collection<ForwardingPathDataDefinition> allPaths = getForwardingPathDataDefinitions(containerComponentId);
1460         List<String> pathIDsToBeDeleted = new ArrayList<>();
1461         allPaths.stream().filter(path -> isPathRelatedToComponent(path, componentInstanceId))
1462             .forEach(path -> pathIDsToBeDeleted.add(path.getUniqueId()));
1463         return pathIDsToBeDeleted;
1464     }
1465
1466     private Collection<ForwardingPathDataDefinition> getForwardingPathDataDefinitions(String containerComponentId) {
1467         ComponentParametersView filter = new ComponentParametersView(true);
1468         filter.setIgnoreServicePath(false);
1469         Either<Service, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getToscaElement(containerComponentId, filter);
1470         return forwardingPathOrigin.left().value().getForwardingPaths().values();
1471     }
1472
1473     private boolean isPathRelatedToComponent(ForwardingPathDataDefinition pathDataDefinition, String componentInstanceId) {
1474         return pathDataDefinition.getPathElements().getListToscaDataDefinition().stream().anyMatch(
1475             elementDataDefinition -> elementDataDefinition.getFromNode().equalsIgnoreCase(componentInstanceId) || elementDataDefinition.getToNode()
1476                 .equalsIgnoreCase(componentInstanceId));
1477     }
1478
1479     private ComponentInstance deleteComponentInstance(Component containerComponent, String componentInstanceId,
1480                                                       ComponentTypeEnum containerComponentType) {
1481         Either<ImmutablePair<Component, String>, StorageOperationStatus> deleteRes = toscaOperationFacade
1482             .deleteComponentInstanceFromTopologyTemplate(containerComponent, componentInstanceId);
1483         if (deleteRes.isRight()) {
1484             log.debug("Failed to delete entry on graph for resourceInstance {}", componentInstanceId);
1485             ActionStatus status = componentsUtils.convertFromStorageResponse(deleteRes.right().value(), containerComponentType);
1486             throw new ByActionStatusComponentException(status, componentInstanceId);
1487         }
1488         log.debug("The component instance {} has been removed from container component {}. ", componentInstanceId, containerComponent);
1489         ComponentInstance deletedInstance = findAndRemoveComponentInstanceFromContainerComponent(componentInstanceId, containerComponent);
1490         if (CollectionUtils.isNotEmpty(containerComponent.getInputs())) {
1491             List<InputDefinition> inputsToDelete = containerComponent.getInputs().stream()
1492                 .filter(i -> i.getInstanceUniqueId() != null && i.getInstanceUniqueId().equals(componentInstanceId)).collect(Collectors.toList());
1493             if (CollectionUtils.isNotEmpty(inputsToDelete)) {
1494                 StorageOperationStatus deleteInputsRes = toscaOperationFacade
1495                     .deleteComponentInstanceInputsFromTopologyTemplate(containerComponent, inputsToDelete);
1496                 if (deleteInputsRes != StorageOperationStatus.OK) {
1497                     log.debug("Failed to delete inputs of the component instance {} from container component. ", componentInstanceId);
1498                     throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(deleteInputsRes, containerComponentType),
1499                         componentInstanceId);
1500                 }
1501             }
1502         }
1503         if (CollectionUtils.isNotEmpty(containerComponent.getOutputs())) {
1504             final List<OutputDefinition> outputsToDelete = containerComponent.getOutputs().stream()
1505                 .filter(i -> i.getInstanceUniqueId() != null && i.getInstanceUniqueId().equals(componentInstanceId)).collect(Collectors.toList());
1506             if (CollectionUtils.isNotEmpty(outputsToDelete)) {
1507                 final StorageOperationStatus deleteOutputsRes = toscaOperationFacade
1508                     .deleteComponentInstanceOutputsFromTopologyTemplate(containerComponent, outputsToDelete);
1509                 if (deleteOutputsRes != StorageOperationStatus.OK) {
1510                     log.debug("Failed to delete outputs of the component instance {} from container component. ", componentInstanceId);
1511                     throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(deleteOutputsRes, containerComponentType),
1512                         componentInstanceId);
1513                 }
1514             }
1515         }
1516         return deletedInstance;
1517     }
1518
1519     private ComponentInstance findAndRemoveComponentInstanceFromContainerComponent(String componentInstanceId, Component containerComponent) {
1520         ComponentInstance foundInstance = null;
1521         for (ComponentInstance instance : containerComponent.getComponentInstances()) {
1522             if (instance.getUniqueId().equals(componentInstanceId)) {
1523                 foundInstance = instance;
1524                 containerComponent.getComponentInstances().remove(instance);
1525                 break;
1526             }
1527         }
1528         findAndRemoveComponentInstanceRelations(componentInstanceId, containerComponent);
1529         return foundInstance;
1530     }
1531
1532     private void findAndRemoveComponentInstanceRelations(String componentInstanceId, Component containerComponent) {
1533         if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstancesRelations())) {
1534             containerComponent.setComponentInstancesRelations(
1535                 containerComponent.getComponentInstancesRelations().stream().filter(r -> isNotBelongingRelation(componentInstanceId, r))
1536                     .collect(Collectors.toList()));
1537         }
1538     }
1539
1540     private boolean isNotBelongingRelation(String componentInstanceId, RequirementCapabilityRelDef relation) {
1541         return !relation.getToNode().equals(componentInstanceId) && !relation.getFromNode().equals(componentInstanceId);
1542     }
1543
1544     public RequirementCapabilityRelDef associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef,
1545                                                        ComponentTypeEnum componentTypeEnum) {
1546         return associateRIToRI(componentId, userId, requirementDef, componentTypeEnum, true);
1547     }
1548
1549     public RequirementCapabilityRelDef associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef,
1550                                                        ComponentTypeEnum componentTypeEnum, boolean needLock) {
1551         validateUserExists(userId);
1552         RequirementCapabilityRelDef requirementCapabilityRelDef;
1553         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId, componentTypeEnum, null);
1554         validateCanWorkOnComponent(containerComponent, userId);
1555         boolean failed = false;
1556         try {
1557             if (needLock) {
1558                 lockComponent(containerComponent, ASSOCIATE_RI_TO_RI);
1559             }
1560             requirementCapabilityRelDef = associateRIToRIOnGraph(containerComponent, requirementDef);
1561         } catch (ComponentException e) {
1562             failed = true;
1563             throw e;
1564         } finally {
1565             if (needLock) {
1566                 unlockComponent(failed, containerComponent);
1567             }
1568         }
1569         return requirementCapabilityRelDef;
1570     }
1571
1572     public RequirementCapabilityRelDef associateRIToRIOnGraph(Component containerComponent, RequirementCapabilityRelDef requirementDef) {
1573         log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH);
1574         Either<RequirementCapabilityRelDef, StorageOperationStatus> result = toscaOperationFacade
1575             .associateResourceInstances(null, containerComponent.getUniqueId(), requirementDef);
1576         if (result.isLeft()) {
1577             log.debug(ENTITY_ON_GRAPH_IS_CREATED);
1578             return result.left().value();
1579         } else {
1580             log.debug("Failed to associate node: {} with node {}", requirementDef.getFromNode(), requirementDef.getToNode());
1581             String fromNameOrId = "";
1582             String toNameOrId = "";
1583             Either<ComponentInstance, StorageOperationStatus> fromResult = getResourceInstanceById(containerComponent, requirementDef.getFromNode());
1584             Either<ComponentInstance, StorageOperationStatus> toResult = getResourceInstanceById(containerComponent, requirementDef.getToNode());
1585             toNameOrId = requirementDef.getFromNode();
1586             fromNameOrId = requirementDef.getFromNode();
1587             if (fromResult.isLeft()) {
1588                 fromNameOrId = fromResult.left().value().getName();
1589             }
1590             if (toResult.isLeft()) {
1591                 toNameOrId = toResult.left().value().getName();
1592             }
1593             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true),
1594                 fromNameOrId, toNameOrId, requirementDef.getRelationships().get(0).getRelation().getRequirement());
1595         }
1596     }
1597
1598     /**
1599      * @param componentId
1600      * @param userId
1601      * @param requirementDefList
1602      * @param componentTypeEnum
1603      * @return
1604      */
1605     public List<RequirementCapabilityRelDef> batchDissociateRIFromRI(String componentId, String userId,
1606                                                                      List<RequirementCapabilityRelDef> requirementDefList,
1607                                                                      ComponentTypeEnum componentTypeEnum) {
1608         validateUserExists(userId);
1609         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId, componentTypeEnum, null);
1610         validateCanWorkOnComponent(containerComponent, userId);
1611         boolean failed = false;
1612         List<RequirementCapabilityRelDef> delOkResult = new ArrayList<>();
1613         try {
1614             lockComponent(containerComponent, ASSOCIATE_RI_TO_RI);
1615             for (RequirementCapabilityRelDef requirementDef : requirementDefList) {
1616                 RequirementCapabilityRelDef requirementCapabilityRelDef = dissociateRIFromRI(componentId, userId, requirementDef,
1617                     containerComponent.getComponentType());
1618                 delOkResult.add(requirementCapabilityRelDef);
1619             }
1620         } catch (ComponentException e) {
1621             failed = true;
1622             throw e;
1623         } finally {
1624             unlockComponent(failed, containerComponent);
1625         }
1626         return delOkResult;
1627     }
1628
1629     public RequirementCapabilityRelDef dissociateRIFromRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef,
1630                                                           ComponentTypeEnum componentTypeEnum) {
1631         validateUserExists(userId);
1632         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId, componentTypeEnum, null);
1633         validateCanWorkOnComponent(containerComponent, userId);
1634         boolean failed = false;
1635         try {
1636             lockComponent(containerComponent, ASSOCIATE_RI_TO_RI);
1637             log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH);
1638             Either<RequirementCapabilityRelDef, StorageOperationStatus> result = toscaOperationFacade
1639                 .dissociateResourceInstances(componentId, requirementDef);
1640             if (result.isLeft()) {
1641                 log.debug(ENTITY_ON_GRAPH_IS_CREATED);
1642                 return result.left().value();
1643             } else {
1644                 log.debug("Failed to dissocaite node  {} from node {}", requirementDef.getFromNode(), requirementDef.getToNode());
1645                 String fromNameOrId = "";
1646                 String toNameOrId = "";
1647                 Either<ComponentInstance, StorageOperationStatus> fromResult = getResourceInstanceById(containerComponent,
1648                     requirementDef.getFromNode());
1649                 Either<ComponentInstance, StorageOperationStatus> toResult = getResourceInstanceById(containerComponent, requirementDef.getToNode());
1650                 toNameOrId = requirementDef.getFromNode();
1651                 fromNameOrId = requirementDef.getFromNode();
1652                 if (fromResult.isLeft()) {
1653                     fromNameOrId = fromResult.left().value().getName();
1654                 }
1655                 if (toResult.isLeft()) {
1656                     toNameOrId = toResult.left().value().getName();
1657                 }
1658                 throw new ByActionStatusComponentException(
1659                     componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), fromNameOrId, toNameOrId,
1660                     requirementDef.getRelationships().get(0).getRelation().getRequirement());
1661             }
1662         } catch (ComponentException e) {
1663             failed = true;
1664             throw e;
1665         } finally {
1666             unlockComponent(failed, containerComponent);
1667         }
1668     }
1669
1670     /**
1671      * Allows to get relation contained in specified component according to received Id
1672      *
1673      * @param componentId
1674      * @param relationId
1675      * @param userId
1676      * @param componentTypeEnum
1677      * @return
1678      */
1679     public Either<RequirementCapabilityRelDef, ResponseFormat> getRelationById(String componentId, String relationId, String userId,
1680                                                                                ComponentTypeEnum componentTypeEnum) {
1681         Either<RequirementCapabilityRelDef, ResponseFormat> resultOp = null;
1682         try {
1683             org.openecomp.sdc.be.model.Component containerComponent = null;
1684             RequirementCapabilityRelDef foundRelation = null;
1685             validateUserExists(userId);
1686             containerComponent = validateComponentExists(componentId, componentTypeEnum, null);
1687             List<RequirementCapabilityRelDef> requirementCapabilityRelations = containerComponent.getComponentInstancesRelations();
1688             foundRelation = findRelation(relationId, requirementCapabilityRelations);
1689             if (foundRelation == null) {
1690                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RELATION_NOT_FOUND, relationId, componentId);
1691                 log.debug("Relation with id {} was not found on the component", relationId, componentId);
1692                 resultOp = Either.right(responseFormat);
1693             }
1694             if (resultOp == null) {
1695                 resultOp = setRelatedCapability(foundRelation, containerComponent);
1696             }
1697             if (resultOp.isLeft()) {
1698                 resultOp = setRelatedRequirement(foundRelation, containerComponent);
1699             }
1700         } catch (Exception e) {
1701             log.error("The exception {} occured upon get relation {} of the component {} ", e, relationId, componentId);
1702             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1703         }
1704         return resultOp;
1705     }
1706
1707     private RequirementCapabilityRelDef findRelation(String relationId, List<RequirementCapabilityRelDef> requirementCapabilityRelations) {
1708         for (RequirementCapabilityRelDef relationship : requirementCapabilityRelations) {
1709             if (relationship.getRelationships().stream().anyMatch(r -> r.getRelation().getId().equals(relationId))) {
1710                 return relationship;
1711             }
1712         }
1713         return null;
1714     }
1715
1716     private Either<RequirementCapabilityRelDef, ResponseFormat> setRelatedRequirement(RequirementCapabilityRelDef foundRelation,
1717                                                                                       Component containerComponent) {
1718         Either<RequirementCapabilityRelDef, ResponseFormat> result = null;
1719         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1720         String instanceId = foundRelation.getFromNode();
1721         Optional<RequirementDefinition> foundRequirement;
1722         Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(instanceId))
1723             .findFirst();
1724         if (!instance.isPresent()) {
1725             ResponseFormat responseFormat = componentsUtils
1726                 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance",
1727                     containerComponent.getComponentType().getValue(), containerComponent.getName());
1728             log.debug("Component instance with id {} was not found on the component", instanceId, containerComponent.getUniqueId());
1729             result = Either.right(responseFormat);
1730         }
1731         if (result == null && instance.isPresent()) {
1732             for (List<RequirementDefinition> requirements : instance.get().getRequirements().values()) {
1733                 foundRequirement = requirements.stream()
1734                     .filter(r -> isBelongingCalcRequirement(relationshipInfo, r, containerComponent.getLifecycleState())).findFirst();
1735                 if (foundRequirement.isPresent()) {
1736                     foundRelation.resolveSingleRelationship().setRequirement(foundRequirement.get());
1737                     result = Either.left(foundRelation);
1738                 }
1739             }
1740         }
1741         if (result == null) {
1742             Either<RequirementDataDefinition, StorageOperationStatus> getfulfilledRequirementRes = toscaOperationFacade
1743                 .getFulfilledRequirementByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, this::isBelongingFullRequirement);
1744             if (getfulfilledRequirementRes.isRight()) {
1745                 ResponseFormat responseFormat = componentsUtils
1746                     .getResponseFormat(ActionStatus.REQUIREMENT_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getRequirement(), instanceId,
1747                         containerComponent.getUniqueId());
1748                 log.debug("Requirement {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId,
1749                     containerComponent.getUniqueId());
1750                 result = Either.right(responseFormat);
1751             } else {
1752                 foundRelation.resolveSingleRelationship().setRequirement(getfulfilledRequirementRes.left().value());
1753             }
1754         }
1755         if (result == null) {
1756             result = Either.left(foundRelation);
1757         }
1758         return result;
1759     }
1760
1761     private boolean isBelongingFullRequirement(RelationshipInfo relationshipInfo, RequirementDataDefinition req) {
1762         return req.getName().equals(relationshipInfo.getRequirement()) && req.getUniqueId().equals(relationshipInfo.getRequirementUid()) && req
1763             .getOwnerId().equals(relationshipInfo.getRequirementOwnerId());
1764     }
1765
1766     private boolean isBelongingCalcRequirement(RelationshipInfo relationshipInfo, RequirementDataDefinition req, LifecycleStateEnum state) {
1767         return nameMatches(relationshipInfo.getRequirement(), req.getName(), req.getPreviousName(), state) && req.getUniqueId()
1768             .equals(relationshipInfo.getRequirementUid()) && req.getOwnerId().equals(relationshipInfo.getRequirementOwnerId());
1769     }
1770
1771     private Either<RequirementCapabilityRelDef, ResponseFormat> setRelatedCapability(RequirementCapabilityRelDef foundRelation,
1772                                                                                      Component containerComponent) {
1773         Either<RequirementCapabilityRelDef, ResponseFormat> result = null;
1774         RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation();
1775         String instanceId = foundRelation.getToNode();
1776         Optional<CapabilityDefinition> foundCapability;
1777         Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(instanceId))
1778             .findFirst();
1779         if (!instance.isPresent()) {
1780             ResponseFormat responseFormat = componentsUtils
1781                 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance",
1782                     containerComponent.getComponentType().getValue(), containerComponent.getName());
1783             log.debug("Component instance with id {} was not found on the component", instanceId, containerComponent.getUniqueId());
1784             result = Either.right(responseFormat);
1785         }
1786         if (result == null && instance.isPresent()) {
1787             for (List<CapabilityDefinition> capabilities : instance.get().getCapabilities().values()) {
1788                 foundCapability = capabilities.stream()
1789                     .filter(c -> isBelongingCalcCapability(relationshipInfo, c, containerComponent.getLifecycleState())).findFirst();
1790                 if (foundCapability.isPresent()) {
1791                     foundRelation.resolveSingleRelationship().setCapability(foundCapability.get());
1792                     result = Either.left(foundRelation);
1793                 }
1794             }
1795         }
1796         if (result == null) {
1797             Either<CapabilityDataDefinition, StorageOperationStatus> getfulfilledRequirementRes = toscaOperationFacade
1798                 .getFulfilledCapabilityByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, this::isBelongingFullCapability);
1799             if (getfulfilledRequirementRes.isRight()) {
1800                 ResponseFormat responseFormat = componentsUtils
1801                     .getResponseFormat(ActionStatus.CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getCapability(), instanceId,
1802                         containerComponent.getUniqueId());
1803                 log.debug("Capability {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId,
1804                     containerComponent.getUniqueId());
1805                 result = Either.right(responseFormat);
1806             } else {
1807                 foundRelation.resolveSingleRelationship().setCapability(getfulfilledRequirementRes.left().value());
1808             }
1809         }
1810         if (result == null) {
1811             result = Either.left(foundRelation);
1812         }
1813         return result;
1814     }
1815
1816     private boolean isBelongingFullCapability(RelationshipInfo relationshipInfo, CapabilityDataDefinition cap) {
1817         return cap.getName().equals(relationshipInfo.getCapability()) && cap.getUniqueId().equals(relationshipInfo.getCapabilityUid()) && cap
1818             .getOwnerId().equals(relationshipInfo.getCapabilityOwnerId());
1819     }
1820
1821     private boolean isBelongingCalcCapability(RelationshipInfo relationshipInfo, CapabilityDataDefinition cap, LifecycleStateEnum state) {
1822         return nameMatches(relationshipInfo.getCapability(), cap.getName(), cap.getPreviousName(), state) && cap.getUniqueId()
1823             .equals(relationshipInfo.getCapabilityUid()) && cap.getOwnerId().equals(relationshipInfo.getCapabilityOwnerId());
1824     }
1825
1826     private boolean nameMatches(String nameFromRelationship, String currName, String previousName, LifecycleStateEnum state) {
1827         return state == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT ? currName.equals(nameFromRelationship)
1828             : previousName != null && previousName.equals(nameFromRelationship);
1829     }
1830
1831     private Either<ComponentInstanceProperty, ResponseFormat> updateAttributeValue(ComponentInstanceProperty attribute, String resourceInstanceId) {
1832         Either<ComponentInstanceProperty, StorageOperationStatus> eitherAttribute = componentInstanceOperation
1833             .updateAttributeValueInResourceInstance(attribute, resourceInstanceId, true);
1834         Either<ComponentInstanceProperty, ResponseFormat> result;
1835         if (eitherAttribute.isLeft()) {
1836             log.debug("Attribute value {} was updated on graph.", attribute.getValueUniqueUid());
1837             ComponentInstanceProperty instanceAttribute = eitherAttribute.left().value();
1838             result = Either.left(instanceAttribute);
1839         } else {
1840             log.debug("Failed to update attribute value {} in resource instance {}", attribute, resourceInstanceId);
1841             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(eitherAttribute.right().value());
1842             result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
1843         }
1844         return result;
1845     }
1846
1847     private Either<ComponentInstanceProperty, ResponseFormat> createAttributeValue(ComponentInstanceProperty attribute, String resourceInstanceId) {
1848         Either<ComponentInstanceProperty, ResponseFormat> result;
1849         Wrapper<Integer> indexCounterWrapper = new Wrapper<>();
1850         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1851         validateIncrementCounter(resourceInstanceId, GraphPropertiesDictionary.ATTRIBUTE_COUNTER, indexCounterWrapper, errorWrapper);
1852         if (!errorWrapper.isEmpty()) {
1853             result = Either.right(errorWrapper.getInnerElement());
1854         } else {
1855             Either<ComponentInstanceProperty, StorageOperationStatus> eitherAttribute = componentInstanceOperation
1856                 .addAttributeValueToResourceInstance(attribute, resourceInstanceId, indexCounterWrapper.getInnerElement(), true);
1857             if (eitherAttribute.isLeft()) {
1858                 log.debug("Attribute value was added to resource instance {}", resourceInstanceId);
1859                 ComponentInstanceProperty instanceAttribute = eitherAttribute.left().value();
1860                 result = Either.left(instanceAttribute);
1861             } else {
1862                 log.debug("Failed to add attribute value {}  to resource instance {}", attribute, resourceInstanceId);
1863                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(eitherAttribute.right().value());
1864                 result = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
1865             }
1866         }
1867         return result;
1868     }
1869
1870     /**
1871      * Create Or Updates Attribute Instance
1872      *
1873      * @param componentTypeEnum
1874      * @param componentId
1875      * @param resourceInstanceId
1876      * @param attribute
1877      * @param userId
1878      * @return
1879      */
1880     public Either<ComponentInstanceProperty, ResponseFormat> createOrUpdateAttributeValue(ComponentTypeEnum componentTypeEnum, String componentId,
1881                                                                                           String resourceInstanceId,
1882                                                                                           ComponentInstanceProperty attribute, String userId) {
1883         Either<ComponentInstanceProperty, ResponseFormat> result = null;
1884         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1885         validateUserExists(userId);
1886         if (errorWrapper.isEmpty()) {
1887             validateComponentTypeEnum(componentTypeEnum, "CreateOrUpdateAttributeValue", errorWrapper);
1888         }
1889         if (errorWrapper.isEmpty()) {
1890             validateCanWorkOnComponent(componentId, componentTypeEnum, userId, errorWrapper);
1891         }
1892         if (errorWrapper.isEmpty()) {
1893             validateComponentLock(componentId, componentTypeEnum, errorWrapper);
1894         }
1895         try {
1896             if (errorWrapper.isEmpty()) {
1897                 final boolean isCreate = Objects.isNull(attribute.getValueUniqueUid());
1898                 if (isCreate) {
1899                     result = createAttributeValue(attribute, resourceInstanceId);
1900                 } else {
1901                     result = updateAttributeValue(attribute, resourceInstanceId);
1902                 }
1903             } else {
1904                 result = Either.right(errorWrapper.getInnerElement());
1905             }
1906             return result;
1907         } finally {
1908             if (result == null || result.isRight()) {
1909                 janusGraphDao.rollback();
1910             } else {
1911                 janusGraphDao.commit();
1912             }
1913             // unlock resource
1914             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
1915         }
1916     }
1917
1918     public Either<List<ComponentInstanceProperty>, ResponseFormat> createOrUpdatePropertiesValues(ComponentTypeEnum componentTypeEnum,
1919                                                                                                   String componentId, String resourceInstanceId,
1920                                                                                                   List<ComponentInstanceProperty> properties,
1921                                                                                                   String userId) {
1922         Either<List<ComponentInstanceProperty>, ResponseFormat> resultOp = null;
1923         /*-------------------------------Validations---------------------------------*/
1924         validateUserExists(userId);
1925
1926         if (componentTypeEnum == null) {
1927             BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertiesValues", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
1928             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
1929             return resultOp;
1930         }
1931         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1932
1933         if (getResourceResult.isRight()) {
1934             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
1935             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
1936             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
1937         }
1938         Component containerComponent = getResourceResult.left().value();
1939
1940         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
1941             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
1942                 log.info(COMPONENT_ARCHIVED, componentId);
1943                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
1944             }
1945             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
1946             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1947         }
1948
1949         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
1950         if (resourceInstanceStatus.isRight()) {
1951             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
1952                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
1953         }
1954         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
1955
1956         // lock resource
1957         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
1958         if (lockStatus != StorageOperationStatus.OK) {
1959             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
1960             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
1961         }
1962         List<ComponentInstanceProperty> updatedProperties = new ArrayList<>();
1963         try {
1964             for (ComponentInstanceProperty property : properties) {
1965                 validateMandatoryFields(property);
1966                 validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance);
1967                 String propertyParentUniqueId = property.getParentUniqueId();
1968                 if (property.isToscaFunction()) {
1969                     toscaFunctionValidator.validate(property, containerComponent);
1970                     property.setValue(property.getToscaFunction().getValue());
1971                 }
1972
1973                 if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())){
1974                     final JSONObject jObject  = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
1975                     property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
1976                         setJsonObjectForSubProperty(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
1977                     });
1978                     property.setValue(jObject.toString());
1979                 }
1980                 Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel());
1981                 if (updatedPropertyValue.isRight()) {
1982                     log.error("Failed to update property object value of property: {}",
1983                         property);
1984                     throw new ByResponseFormatComponentException(updatedPropertyValue.right().value());
1985                 }
1986                 Optional<CapabilityDefinition>
1987                     capPropDefinition = getPropertyCapabilityOfChildInstance(propertyParentUniqueId, foundResourceInstance.getCapabilities());
1988                 if (capPropDefinition.isPresent()) {
1989                     updatedPropertyValue
1990                         .bimap(updatedValue -> updateCapabilityPropFromUpdateInstProp(property, updatedValue,
1991                             containerComponent, foundResourceInstance, capPropDefinition.get().getType(),
1992                             capPropDefinition.get().getName()), Either::right);
1993                 } else {
1994                     updatedPropertyValue.bimap(
1995                         updatedValue -> updatePropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance),
1996                         Either::right
1997                     );
1998                     updatedProperties.add(property);
1999                 }
2000             }
2001
2002             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2003                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2004             if (updateContainerRes.isRight()) {
2005                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2006                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2007                 return resultOp;
2008             }
2009             resultOp = Either.left(updatedProperties);
2010             return resultOp;
2011
2012         } catch (final ComponentException e) {
2013             return Either.right(e.getResponseFormat());
2014         } finally {
2015             if (resultOp == null || resultOp.isRight()) {
2016                 janusGraphDao.rollback();
2017             } else {
2018                 janusGraphDao.commit();
2019             }
2020             // unlock resource
2021             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2022         }
2023     }
2024     
2025     private void setJsonObjectForSubProperty(final JSONObject jObject, final List<String> path, String value) {
2026         if (path.size() == 1) {
2027             Object valueAsObject = new Yaml().loadAs(value, Object.class);
2028             jObject.put(path.get(0), valueAsObject);
2029         } else {
2030             if (!jObject.has(path.get(0))) {
2031                 jObject.put(path.get(0), new JSONObject());
2032             }
2033             final JSONObject jsonObject = jObject.getJSONObject(path.get(0));
2034             setJsonObjectForSubProperty(jsonObject, path.subList(1, path.size()), value);
2035         }
2036     }
2037
2038     public Either<List<ComponentInstanceAttribute>, ResponseFormat> createOrUpdateAttributeValues(final ComponentTypeEnum componentTypeEnum,
2039                                                                                                   final String componentId,
2040                                                                                                   final String resourceInstanceId,
2041                                                                                                   final List<ComponentInstanceAttribute> attributes,
2042                                                                                                   final String userId) {
2043         Either<List<ComponentInstanceAttribute>, ResponseFormat> resultOp = null;
2044         /*-------------------------------Validations---------------------------------*/
2045         validateUserExists(userId);
2046
2047         if (componentTypeEnum == null) {
2048             BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertiesValues", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2049             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2050             return resultOp;
2051         }
2052         final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade
2053             .getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2054
2055         if (getResourceResult.isRight()) {
2056             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
2057             final ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
2058             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
2059         }
2060         final Component containerComponent = getResourceResult.left().value();
2061
2062         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
2063             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
2064                 log.info(COMPONENT_ARCHIVED, componentId);
2065                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
2066             }
2067             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
2068             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2069         }
2070
2071         final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
2072             resourceInstanceId);
2073         if (resourceInstanceStatus.isRight()) {
2074             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
2075                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
2076         }
2077         final ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
2078
2079         // lock resource
2080         final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2081         if (lockStatus != StorageOperationStatus.OK) {
2082             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2083             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2084         }
2085         final List<ComponentInstanceAttribute> updatedProperties = new ArrayList<>();
2086         try {
2087             for (final ComponentInstanceAttribute attribute : attributes) {
2088                 final ComponentInstanceAttribute componentInstanceProperty = validateAttributeExistsOnComponent(attribute, containerComponent,
2089                     foundResourceInstance);
2090                 final Either<String, ResponseFormat> updatedPropertyValue = updateAttributeObjectValue(attribute);
2091                 if (updatedPropertyValue.isRight()) {
2092                     log.error("Failed to update attribute object value of attribute: {}", attribute);
2093                     throw new ByResponseFormatComponentException(updatedPropertyValue.right().value());
2094                 }
2095                 updatedPropertyValue.bimap(
2096                     updatedValue -> {
2097                         componentInstanceProperty.setValue(updatedValue);
2098                         return updateAttributeOnContainerComponent(attribute, updatedValue,
2099                             containerComponent, foundResourceInstance);
2100                     }, Either::right);
2101                 updatedProperties.add(componentInstanceProperty);
2102             }
2103
2104             final Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2105                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2106             if (updateContainerRes.isRight()) {
2107                 final ActionStatus actionStatus = componentsUtils
2108                     .convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2109                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2110                 return resultOp;
2111             }
2112             resultOp = Either.left(updatedProperties);
2113             return resultOp;
2114
2115         } catch (final ComponentException e) {
2116             return Either.right(e.getResponseFormat());
2117         } finally {
2118             if (resultOp == null || resultOp.isRight()) {
2119                 janusGraphDao.rollback();
2120             } else {
2121                 janusGraphDao.commit();
2122             }
2123             // unlock resource
2124             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2125         }
2126     }
2127
2128     private void validateMandatoryFields(PropertyDataDefinition property) {
2129         if (StringUtils.isEmpty(property.getName())) {
2130             throw new ByActionStatusComponentException(ActionStatus.MISSING_PROPERTY_NAME);
2131         }
2132     }
2133
2134     private void validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent,
2135                                                                         ComponentInstance foundResourceInstance) {
2136         List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties()
2137             .get(foundResourceInstance.getUniqueId());
2138         final boolean hasProperty = instanceProperties.stream().anyMatch(p -> p.getName().equals(property.getName()));
2139         if (!hasProperty) {
2140             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, property.getName());
2141         }
2142     }
2143
2144     private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute,
2145                                                                           final Component containerComponent,
2146                                                                           final ComponentInstance foundResourceInstance) {
2147         final List<ComponentInstanceAttribute> instanceProperties =
2148             containerComponent.getComponentInstancesAttributes().get(foundResourceInstance.getUniqueId());
2149         final Optional<ComponentInstanceAttribute> instanceAttribute =
2150             instanceProperties.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
2151         if (!instanceAttribute.isPresent()) {
2152             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName());
2153         }
2154         return instanceAttribute.get();
2155     }
2156
2157     private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property,
2158                                                                         String newValue, Component containerComponent,
2159                                                                         ComponentInstance foundResourceInstance,
2160                                                                         String capabilityType, String capabilityName) {
2161         String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
2162         ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
2163             foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId);
2164         if (actionStatus != null) {
2165             return actionStatus;
2166         }
2167
2168         return componentsUtils.getResponseFormat(ActionStatus.OK);
2169     }
2170
2171     private ResponseFormat updateCapabilityPropFromUpdateInstProp(ComponentInstanceProperty property,
2172                                                                   String newValue, Component containerComponent,
2173                                                                   ComponentInstance foundResourceInstance,
2174                                                                   String capabilityType, String capabilityName) {
2175         String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
2176         Either<Component, StorageOperationStatus> getComponentRes =
2177             toscaOperationFacade.getToscaFullElement(foundResourceInstance.getComponentUid());
2178         if (getComponentRes.isRight()) {
2179             return componentsUtils.getResponseFormat(getComponentRes.right().value());
2180         }
2181
2182         ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
2183             foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId);
2184         if (actionStatus != null) {
2185             return actionStatus;
2186         }
2187
2188         return componentsUtils.getResponseFormat(ActionStatus.OK);
2189     }
2190
2191     private ResponseFormat updateCapPropOnContainerComponent(ComponentInstanceProperty property, String newValue,
2192                                                              Component containerComponent,
2193                                                              ComponentInstance foundResourceInstance,
2194                                                              String capabilityType, String capabilityName,
2195                                                              String componentInstanceUniqueId) {
2196         Map<String, List<CapabilityDefinition>> capabilities =
2197             Optional.ofNullable(foundResourceInstance.getCapabilities()).orElse(Collections.emptyMap());
2198         List<CapabilityDefinition> capPerType =
2199             Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.emptyList());
2200         Optional<CapabilityDefinition> cap =
2201             capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny();
2202         if (cap.isPresent()) {
2203             List<ComponentInstanceProperty> capProperties = cap.get().getProperties();
2204             if (capProperties != null) {
2205                 Optional<ComponentInstanceProperty> instanceProperty =
2206                     capProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
2207                 StorageOperationStatus status;
2208                 if (instanceProperty.isPresent()) {
2209                     String capKey = ModelConverter
2210                         .buildCapabilityPropertyKey(foundResourceInstance.getOriginType().isAtomicType(), capabilityType, capabilityName,
2211                             componentInstanceUniqueId, cap.get());
2212                     instanceProperty.get().setValue(newValue);
2213                     List<String> path = new ArrayList<>();
2214                     path.add(componentInstanceUniqueId);
2215                     path.add(capKey);
2216                     instanceProperty.get().setPath(path);
2217                     status = toscaOperationFacade.updateComponentInstanceCapabiltyProperty(containerComponent,
2218                         componentInstanceUniqueId, capKey, instanceProperty.get());
2219                     if (status != StorageOperationStatus.OK) {
2220                         ActionStatus actionStatus =
2221                             componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2222                         return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2223
2224                     }
2225                     foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2226                 }
2227             }
2228         }
2229         return null;
2230     }
2231
2232     private ResponseFormat updatePropertyOnContainerComponent(ComponentInstanceProperty instanceProperty, String newValue,
2233                                                               Component containerComponent, ComponentInstance foundResourceInstance) {
2234         StorageOperationStatus status;
2235         instanceProperty.setValue(newValue);
2236         status = toscaOperationFacade.updateComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(), instanceProperty);
2237         if (status != StorageOperationStatus.OK) {
2238             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2239             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2240         }
2241         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2242         return componentsUtils.getResponseFormat(ActionStatus.OK);
2243     }
2244
2245     private ResponseFormat updateAttributeOnContainerComponent(final ComponentInstanceAttribute instanceAttribute,
2246                                                                final String newValue,
2247                                                                final Component containerComponent,
2248                                                                final ComponentInstance foundResourceInstance) {
2249
2250         instanceAttribute.setValue(newValue);
2251         final StorageOperationStatus status =
2252             toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), instanceAttribute);
2253         if (status != StorageOperationStatus.OK) {
2254             final ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2255             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2256         }
2257         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2258         return componentsUtils.getResponseFormat(ActionStatus.OK);
2259     }
2260
2261     private <T extends PropertyDefinition> Either<String, ResponseFormat> validatePropertyObjectValue(T property, String newValue, boolean isInput) {
2262         final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel());
2263         String propertyType = property.getType();
2264         String innerType = getInnerType(property);
2265
2266         // Specific Update Logic
2267         Either<Object, Boolean> isValid = propertyOperation
2268             .validateAndUpdatePropertyValue(property.getType(), newValue, true, innerType, allDataTypes);
2269         if (isValid.isRight()) {
2270             if (!Boolean.TRUE.equals(isValid.right().value())) {
2271                 log.error("Invalid value {} of property {} ", newValue, property.getName());
2272                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2273             }
2274         } else {
2275             Object object = isValid.left().value();
2276             if (object != null) {
2277                 newValue = object.toString();
2278             }
2279         }
2280         if (validateAndUpdateRules(property, isInput, allDataTypes, innerType, propertyType)) {
2281             return Either.right(componentsUtils.getResponseFormat(componentsUtils
2282                 .convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
2283         }
2284         return Either.left(newValue);
2285     }
2286
2287     private <T extends PropertyDefinition> boolean validateAndUpdateRules(T property, boolean isInput, Map<String, DataTypeDefinition> allDataTypes,
2288                                                                           String innerType, String propertyType) {
2289         if (!isInput) {
2290             ImmutablePair<String, Boolean> pair = propertyOperation
2291                 .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
2292             if (pair.getRight() != null && !pair.getRight()) {
2293                 BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
2294                 return true;
2295             }
2296         }
2297         return false;
2298     }
2299
2300     private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, final String model) {
2301         final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
2302         String innerType = null;
2303         String propertyType = property.getType();
2304         ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
2305         log.debug("The type of the property {} is {}", property.getUniqueId(), propertyType);
2306
2307         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
2308             SchemaDefinition schema = property.getSchema();
2309             if (schema == null) {
2310                 log.debug("Schema doesn't exists for property of type {}", type);
2311                 return Either
2312                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2313             }
2314             PropertyDataDefinition propDef = schema.getProperty();
2315             if (propDef == null) {
2316                 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
2317                 return Either
2318                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2319             }
2320             innerType = propDef.getType();
2321         }
2322
2323         // Specific Update Logic
2324         String newValue = property.getValue();
2325
2326         if (property.hasToscaFunction() || CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
2327             return Either.left(newValue);
2328         }
2329
2330         Either<Object, Boolean> isValid = propertyOperation
2331             .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes);
2332         if (isValid.isRight()) {
2333             if (!Boolean.TRUE.equals(isValid.right().value())) {
2334                 log.debug("validate and update property value has failed with value: {}", property.getValue());
2335                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
2336                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
2337             }
2338         } else {
2339             Object object = isValid.left().value();
2340             if (object != null) {
2341                 newValue = object.toString();
2342             }
2343         }
2344         ImmutablePair<String, Boolean> pair = propertyOperation
2345             .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
2346         if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
2347             BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
2348             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
2349                 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
2350         }
2351         return Either.left(newValue);
2352     }
2353
2354     private <T extends AttributeDefinition> Either<String, ResponseFormat> updateAttributeObjectValue(final T attribute) {
2355         String innerType = null;
2356         final String attributeType = attribute.getType();
2357         final ToscaPropertyType type = ToscaPropertyType.isValidType(attributeType);
2358         log.debug("The type of the attribute {} is {}", attribute.getUniqueId(), attributeType);
2359
2360         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
2361             final SchemaDefinition def = attribute.getSchema();
2362             if (def == null) {
2363                 log.debug("Schema doesn't exists for attribute of type {}", type);
2364                 return Either
2365                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2366             }
2367             PropertyDataDefinition propDef = def.getProperty();
2368             if (propDef == null) {
2369                 log.debug("Property in Schema Definition inside attribute of type {} doesn't exist", type);
2370                 return Either
2371                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2372             }
2373             innerType = propDef.getType();
2374         }
2375
2376         // Specific Update Logic
2377         String newValue = attribute.getValue();
2378
2379         final var isValid = attributeOperation.validateAndUpdateAttributeValue(attribute, innerType,
2380             componentsUtils.getAllDataTypes(applicationDataTypeCache, attribute.getModel()));
2381         if (isValid.isRight()) {
2382             final Boolean res = isValid.right().value();
2383             if (!Boolean.TRUE.equals(res)) {
2384                 log.debug("validate and update attribute value has failed with value: {}", newValue);
2385                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
2386                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
2387             }
2388         } else {
2389             final Object object = isValid.left().value();
2390             if (object != null) {
2391                 newValue = object.toString();
2392             }
2393         }
2394         return Either.left(newValue);
2395     }
2396
2397     private <T extends PropertyDefinition> void validateToscaGetFunction(T property, Component parentComponent) {
2398         final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
2399         validateGetToscaFunctionAttributes(toscaGetFunction);
2400         validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource());
2401         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) {
2402             validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel());
2403             return;
2404         }
2405         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) {
2406             if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
2407                 validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel());
2408             } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
2409                 final ComponentInstance componentInstance =
2410                     parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
2411                         .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
2412                 validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel());
2413             }
2414
2415             return;
2416         }
2417         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) {
2418             if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
2419                 validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel());
2420             } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
2421                 final ComponentInstance componentInstance =
2422                     parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
2423                         .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
2424                 validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel());
2425             }
2426
2427             return;
2428         }
2429
2430         throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get();
2431     }
2432
2433     private <T extends PropertyDefinition> void validateGetFunction(final T property,
2434                                                                     final List<? extends ToscaPropertyData> parentProperties,
2435                                                                     final String model) {
2436         final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
2437         if (CollectionUtils.isEmpty(parentProperties)) {
2438             throw ToscaGetFunctionExceptionSupplier
2439                 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(),
2440                     toscaGetFunction.getFunctionType()
2441                 ).get();
2442         }
2443         final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId();
2444         ToscaPropertyData referredProperty = parentProperties.stream()
2445             .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId()))
2446             .findFirst()
2447             .orElseThrow(ToscaGetFunctionExceptionSupplier
2448                 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource()
2449                     , toscaGetFunction.getFunctionType())
2450             );
2451         if (toscaGetFunction.isSubProperty()) {
2452             referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
2453         }
2454
2455         if (!property.getType().equals(referredProperty.getType())) {
2456             throw ToscaGetFunctionExceptionSupplier
2457                 .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get();
2458         }
2459         if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) {
2460             throw ToscaGetFunctionExceptionSupplier
2461                 .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get();
2462         }
2463     }
2464
2465     private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty,
2466                                               final ToscaGetFunctionDataDefinition toscaGetFunction,
2467                                               final String model) {
2468         final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model);
2469         final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource();
2470         DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType());
2471         if (dataType == null) {
2472             throw ToscaGetFunctionExceptionSupplier
2473                 .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get();
2474         }
2475         ToscaPropertyData foundProperty = referredProperty;
2476         for (int i = 1; i < propertyPathFromSource.size(); i++) {
2477             final String currentPropertyName = propertyPathFromSource.get(i);
2478             foundProperty = dataType.getProperties().stream()
2479                 .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst()
2480                 .orElseThrow(
2481                     ToscaGetFunctionExceptionSupplier
2482                         .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(),
2483                             toscaGetFunction.getFunctionType())
2484                 );
2485             dataType = dataTypeMap.get(foundProperty.getType());
2486             if (dataType == null) {
2487                 throw ToscaGetFunctionExceptionSupplier
2488                     .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(),
2489                         toscaGetFunction.getFunctionType()).get();
2490             }
2491         }
2492         return foundProperty;
2493     }
2494
2495     private Map<String, DataTypeDefinition> loadDataTypes(String model) {
2496         final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither =
2497             applicationDataTypeCache.getAll(model);
2498         if (dataTypeEither.isRight()) {
2499             throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get();
2500         }
2501         return dataTypeEither.left().value();
2502     }
2503
2504     private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) {
2505         if (functionType == ToscaGetFunctionType.GET_INPUT && propertySource != PropertySource.SELF) {
2506             throw ToscaGetFunctionExceptionSupplier
2507                 .targetSourceNotSupported(functionType, propertySource).get();
2508         }
2509         if (functionType == ToscaGetFunctionType.GET_PROPERTY && !List.of(PropertySource.SELF, PropertySource.INSTANCE).contains(propertySource)) {
2510             throw ToscaGetFunctionExceptionSupplier
2511                 .targetSourceNotSupported(functionType, propertySource).get();
2512         }
2513     }
2514
2515     private void validateGetToscaFunctionAttributes(final ToscaGetFunctionDataDefinition toscaGetFunction) {
2516         if (toscaGetFunction.getFunctionType() == null) {
2517             throw ToscaGetFunctionExceptionSupplier.targetFunctionTypeNotFound().get();
2518         }
2519         if (toscaGetFunction.getPropertySource() == null) {
2520             throw ToscaGetFunctionExceptionSupplier.targetPropertySourceNotFound(toscaGetFunction.getFunctionType()).get();
2521         }
2522         if (CollectionUtils.isEmpty(toscaGetFunction.getPropertyPathFromSource())) {
2523             throw ToscaGetFunctionExceptionSupplier
2524                 .targetSourcePathNotFound(toscaGetFunction.getFunctionType()).get();
2525         }
2526         if (StringUtils.isEmpty(toscaGetFunction.getSourceName()) || StringUtils.isBlank(toscaGetFunction.getSourceName())) {
2527             throw ToscaGetFunctionExceptionSupplier.sourceNameNotFound(toscaGetFunction.getPropertySource()).get();
2528         }
2529         if (StringUtils.isEmpty(toscaGetFunction.getSourceUniqueId()) || StringUtils.isBlank(toscaGetFunction.getSourceUniqueId())) {
2530             throw ToscaGetFunctionExceptionSupplier.sourceIdNotFound(toscaGetFunction.getPropertySource()).get();
2531         }
2532         if (StringUtils.isEmpty(toscaGetFunction.getPropertyName()) || StringUtils.isBlank(toscaGetFunction.getPropertyName())) {
2533             throw ToscaGetFunctionExceptionSupplier.propertyNameNotFound(toscaGetFunction.getPropertySource()).get();
2534         }
2535         if (StringUtils.isEmpty(toscaGetFunction.getPropertyUniqueId()) || StringUtils.isBlank(toscaGetFunction.getPropertyUniqueId())) {
2536             throw ToscaGetFunctionExceptionSupplier.propertyIdNotFound(toscaGetFunction.getPropertySource()).get();
2537         }
2538     }
2539
2540     private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent,
2541                                                            ComponentInstance foundResourceInstance) {
2542         StorageOperationStatus status;
2543         input.setValue(newValue);
2544         status = toscaOperationFacade.updateComponentInstanceInput(containerComponent, foundResourceInstance.getUniqueId(), input);
2545         if (status != StorageOperationStatus.OK) {
2546             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2547             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2548         }
2549         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2550         return componentsUtils.getResponseFormat(ActionStatus.OK);
2551     }
2552
2553     public Either<List<ComponentInstanceInput>, ResponseFormat> createOrUpdateInstanceInputValues(ComponentTypeEnum componentTypeEnum,
2554                                                                                                   String componentId, String resourceInstanceId,
2555                                                                                                   List<ComponentInstanceInput> inputs,
2556                                                                                                   String userId) {
2557
2558         Either<List<ComponentInstanceInput>, ResponseFormat> resultOp = null;
2559
2560         validateUserExists(userId);
2561
2562         if (componentTypeEnum == null) {
2563             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2564             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2565             return resultOp;
2566         }
2567         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2568
2569         if (getResourceResult.isRight()) {
2570             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
2571             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
2572             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
2573         }
2574         Component containerComponent = getResourceResult.left().value();
2575
2576         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
2577             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
2578                 log.info(COMPONENT_ARCHIVED, componentId);
2579                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
2580             }
2581             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
2582             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2583             return resultOp;
2584         }
2585         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
2586         if (resourceInstanceStatus.isRight()) {
2587             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
2588                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
2589         }
2590
2591         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
2592
2593         // lock resource
2594         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2595         if (lockStatus != StorageOperationStatus.OK) {
2596             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2597             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2598         }
2599         List<ComponentInstanceInput> updatedInputs = new ArrayList<>();
2600         try {
2601             for (ComponentInstanceInput input : inputs) {
2602                 validateMandatoryFields(input);
2603                 ComponentInstanceInput componentInstanceInput = validateInputExistsOnComponent(input, containerComponent, foundResourceInstance);
2604                 Either<String, ResponseFormat> validatedInputValue = validatePropertyObjectValue(componentInstanceInput, input.getValue(), true);
2605                 if (validatedInputValue.isRight()) {
2606                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT, input.getName());
2607                 }
2608                 updateInputOnContainerComponent(componentInstanceInput, validatedInputValue.left().value(), containerComponent,
2609                     foundResourceInstance);
2610                 updatedInputs.add(componentInstanceInput);
2611             }
2612             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2613                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2614             if (updateContainerRes.isRight()) {
2615                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2616                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2617                 return resultOp;
2618             }
2619             resultOp = Either.left(updatedInputs);
2620             return resultOp;
2621
2622         } finally {
2623             if (resultOp == null || resultOp.isRight()) {
2624                 janusGraphDao.rollback();
2625             } else {
2626                 janusGraphDao.commit();
2627             }
2628             // unlock resource
2629             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2630         }
2631
2632     }
2633
2634     private ComponentInstanceInput validateInputExistsOnComponent(ComponentInstanceInput input, Component containerComponent,
2635                                                                   ComponentInstance foundResourceInstance) {
2636         List<ComponentInstanceInput> instanceProperties = containerComponent.getComponentInstancesInputs().get(foundResourceInstance.getUniqueId());
2637         Optional<ComponentInstanceInput> instanceInput = instanceProperties.stream().filter(p -> p.getName().equals(input.getName())).findAny();
2638         if (!instanceInput.isPresent()) {
2639             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, input.getName());
2640         }
2641         return instanceInput.get();
2642     }
2643
2644     public Either<ComponentInstanceProperty, ResponseFormat> createOrUpdateGroupInstancePropertyValue(ComponentTypeEnum componentTypeEnum,
2645                                                                                                       String componentId, String resourceInstanceId,
2646                                                                                                       String groupInstanceId,
2647                                                                                                       ComponentInstanceProperty property,
2648                                                                                                       String userId) {
2649
2650         Either<ComponentInstanceProperty, ResponseFormat> resultOp = null;
2651
2652         validateUserExists(userId);
2653
2654         if (componentTypeEnum == null) {
2655             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2656             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2657             return resultOp;
2658         }
2659
2660         if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
2661             log.info("Restricted operation for user: {} on service: {}", userId, componentId);
2662             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2663             return resultOp;
2664         }
2665         // lock resource
2666         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2667         if (lockStatus != StorageOperationStatus.OK) {
2668             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2669             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2670             return resultOp;
2671         }
2672         try {
2673             String propertyValueUid = property.getValueUniqueUid();
2674
2675             if (propertyValueUid == null) {
2676
2677                 Either<Integer, StorageOperationStatus> counterRes = groupInstanceOperation
2678                     .increaseAndGetGroupInstancePropertyCounter(groupInstanceId);
2679
2680                 if (counterRes.isRight()) {
2681                     log.debug("increaseAndGetResourcePropertyCounter failed resource instance: {} property: {}", resourceInstanceId, property);
2682                     StorageOperationStatus status = counterRes.right().value();
2683                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2684                     resultOp = Either.right(componentsUtils.getResponseFormat(actionStatus));
2685                 }
2686                 Integer index = counterRes.left().value();
2687                 Either<ComponentInstanceProperty, StorageOperationStatus> result = groupInstanceOperation
2688                     .addPropertyValueToGroupInstance(property, resourceInstanceId, index, true);
2689
2690                 if (result.isLeft()) {
2691                     log.trace("Property value was added to resource instance {}", resourceInstanceId);
2692                     ComponentInstanceProperty instanceProperty = result.left().value();
2693
2694                     resultOp = Either.left(instanceProperty);
2695
2696                 } else {
2697                     log.debug("Failed to add property value: {} to resource instance {}", property, resourceInstanceId);
2698
2699                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2700
2701                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2702                 }
2703
2704             } else {
2705                 Either<ComponentInstanceProperty, StorageOperationStatus> result = groupInstanceOperation
2706                     .updatePropertyValueInGroupInstance(property, resourceInstanceId, true);
2707
2708                 if (result.isLeft()) {
2709                     log.debug("Property value {} was updated on graph.", property.getValueUniqueUid());
2710                     ComponentInstanceProperty instanceProperty = result.left().value();
2711
2712                     resultOp = Either.left(instanceProperty);
2713
2714                 } else {
2715                     log.debug("Failed to update property value: {}, in resource instance {}", property, resourceInstanceId);
2716
2717                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2718
2719                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2720                 }
2721             }
2722             if (resultOp.isLeft()) {
2723                 StorageOperationStatus updateCustomizationUUID = componentInstanceOperation.updateCustomizationUUID(resourceInstanceId);
2724                 if (updateCustomizationUUID != StorageOperationStatus.OK) {
2725                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateCustomizationUUID);
2726
2727                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2728
2729                 }
2730             }
2731             return resultOp;
2732
2733         } finally {
2734             if (resultOp == null || resultOp.isRight()) {
2735                 janusGraphDao.rollback();
2736             } else {
2737                 janusGraphDao.commit();
2738             }
2739             // unlock resource
2740             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2741         }
2742
2743     }
2744
2745     public Either<ComponentInstanceProperty, ResponseFormat> deletePropertyValue(ComponentTypeEnum componentTypeEnum, String serviceId,
2746                                                                                  String resourceInstanceId, String propertyValueId, String userId) {
2747
2748         validateUserExists(userId);
2749
2750         Either<ComponentInstanceProperty, ResponseFormat> resultOp = null;
2751
2752         if (componentTypeEnum == null) {
2753             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2754             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2755             return resultOp;
2756         }
2757
2758         if (!ComponentValidationUtils.canWorkOnComponent(serviceId, toscaOperationFacade, userId)) {
2759             log.info("Restricted operation for user {} on service {}", userId, serviceId);
2760             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2761             return resultOp;
2762         }
2763         // lock resource
2764         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(serviceId, componentTypeEnum.getNodeType());
2765         if (lockStatus != StorageOperationStatus.OK) {
2766             log.debug(FAILED_TO_LOCK_SERVICE, serviceId);
2767             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2768             return resultOp;
2769         }
2770         try {
2771             Either<ComponentInstanceProperty, StorageOperationStatus> result = propertyOperation
2772                 .removePropertyValueFromResourceInstance(propertyValueId, resourceInstanceId, true);
2773
2774             if (result.isLeft()) {
2775                 log.debug("Property value {} was removed from graph.", propertyValueId);
2776                 ComponentInstanceProperty instanceProperty = result.left().value();
2777
2778                 resultOp = Either.left(instanceProperty);
2779                 return resultOp;
2780
2781             } else {
2782                 log.debug("Failed to remove property value {} in resource instance {}", propertyValueId, resourceInstanceId);
2783
2784                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2785
2786                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2787
2788                 return resultOp;
2789             }
2790
2791         } finally {
2792             if (resultOp == null || resultOp.isRight()) {
2793                 janusGraphDao.rollback();
2794             } else {
2795                 janusGraphDao.commit();
2796             }
2797             // unlock resource
2798             graphLockOperation.unlockComponent(serviceId, componentTypeEnum.getNodeType());
2799         }
2800
2801     }
2802
2803     private Component getAndValidateOriginComponentOfComponentInstance(Component containerComponent, ComponentInstance componentInstance) {
2804
2805         ComponentTypeEnum componentType = getComponentTypeByParentComponentType(containerComponent.getComponentType());
2806         Component component;
2807         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
2808         if (getComponentRes.isRight()) {
2809             log.debug("Failed to get the component with id {} for component instance {} creation. ", componentInstance.getComponentUid(),
2810                 componentInstance.getName());
2811             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentRes.right().value(), componentType);
2812             throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING);
2813         }
2814         component = getComponentRes.left().value();
2815         LifecycleStateEnum resourceCurrState = component.getLifecycleState();
2816         if (resourceCurrState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
2817             ActionStatus actionStatus = ActionStatus.CONTAINER_CANNOT_CONTAIN_COMPONENT_IN_STATE;
2818             throw new ByActionStatusComponentException(actionStatus, containerComponent.getComponentType().toString(), resourceCurrState.toString());
2819         }
2820         if (Boolean.TRUE.equals(component.isArchived())) {
2821             ActionStatus actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
2822             throw new ByActionStatusComponentException(actionStatus, component.getName());
2823         }
2824         final Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
2825         if (MapUtils.isNotEmpty(componentInterfaces)) {
2826             componentInterfaces.forEach(componentInstance::addInterface);
2827         }
2828         return component;
2829     }
2830
2831     public Either<Set<String>, ResponseFormat> forwardingPathOnVersionChange(String containerComponentParam,
2832                                                                              String containerComponentId,
2833                                                                              String componentInstanceId,
2834                                                                              ComponentInstance newComponentInstance) {
2835         Either<Set<String>, ResponseFormat> resultOp;
2836         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
2837         ComponentParametersView componentParametersView = getComponentParametersViewForForwardingPath();
2838
2839         //Fetch Component
2840         Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, componentParametersView);
2841
2842         //Fetch current component instance
2843         Either<ComponentInstance, StorageOperationStatus> eitherResourceInstance =
2844             getResourceInstanceById(containerComponent, componentInstanceId);
2845         if (eitherResourceInstance.isRight()) {
2846             resultOp = Either.right(componentsUtils.getResponseFormat(
2847                 ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId, containerComponentId));
2848             return resultOp;
2849         }
2850         ComponentInstance currentResourceInstance = eitherResourceInstance.left().value();
2851
2852         //Check whether new componentInstance exists
2853         String resourceId = newComponentInstance.getComponentUid();
2854         Either<Boolean, StorageOperationStatus> componentExistsRes = toscaOperationFacade.validateComponentExists(resourceId);
2855         if (componentExistsRes.isRight()) {
2856             log.debug("Failed to find resource {}", resourceId);
2857             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse
2858                 (componentExistsRes.right().value()), resourceId));
2859             return resultOp;
2860         } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
2861             log.debug("The resource {} not found ", resourceId);
2862             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
2863             return resultOp;
2864         }
2865
2866         //Fetch component using new component instance uid
2867         Component updatedContainerComponent = getOriginComponentFromComponentInstance(newComponentInstance);
2868         Set<String> toDeleteForwardingPaths = getForwardingPaths(containerComponent,
2869             currentResourceInstance, updatedContainerComponent);
2870         resultOp = Either.left(toDeleteForwardingPaths);
2871
2872         return resultOp;
2873     }
2874
2875     private Set<String> getForwardingPaths(Component containerComponent, ComponentInstance currentResourceInstance,
2876                                            Component updatedContainerComponent) {
2877         DataForMergeHolder dataForMergeHolder = new DataForMergeHolder();
2878         dataForMergeHolder.setOrigComponentInstId(currentResourceInstance.getName());
2879
2880         Service service = (Service) containerComponent;
2881         ForwardingPathUtils forwardingPathUtils = new ForwardingPathUtils();
2882
2883         return forwardingPathUtils.
2884             getForwardingPathsToBeDeletedOnVersionChange(service, dataForMergeHolder, updatedContainerComponent);
2885     }
2886
2887     private ComponentParametersView getComponentParametersViewForForwardingPath() {
2888         ComponentParametersView componentParametersView = new ComponentParametersView();
2889         componentParametersView.setIgnoreCapabiltyProperties(false);
2890         componentParametersView.setIgnoreServicePath(false);
2891         return componentParametersView;
2892     }
2893
2894     public ComponentInstance changeComponentInstanceVersion(String containerComponentParam, String containerComponentId, String componentInstanceId,
2895                                                             String userId, ComponentInstance newComponentInstance) {
2896
2897         User user = validateUserExists(userId);
2898         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
2899         ComponentParametersView componentParametersView = new ComponentParametersView();
2900         componentParametersView.setIgnoreCapabiltyProperties(false);
2901
2902         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType,
2903             componentParametersView);
2904
2905         validateCanWorkOnComponent(containerComponent, userId);
2906
2907         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceId);
2908         if (resourceInstanceStatus.isRight()) {
2909             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId,
2910                 containerComponentId);
2911         }
2912
2913         ComponentInstance currentResourceInstance = resourceInstanceStatus.left().value();
2914
2915         return changeInstanceVersion(containerComponent, currentResourceInstance, newComponentInstance, user, containerComponentType);
2916     }
2917
2918     public ComponentInstance changeInstanceVersion(org.openecomp.sdc.be.model.Component containerComponent,
2919                                                    ComponentInstance currentResourceInstance,
2920                                                    ComponentInstance newComponentInstance,
2921                                                    User user,
2922                                                    final ComponentTypeEnum containerComponentType) {
2923         boolean failed = false;
2924         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus;
2925
2926         try {
2927             lockComponent(containerComponent, "changeComponentInstanceVersion");
2928             String containerComponentId = containerComponent.getUniqueId();
2929             String componentInstanceId = currentResourceInstance.getUniqueId();
2930             if (currentResourceInstance.getComponentUid().equals(newComponentInstance.getComponentUid())) {
2931                 return currentResourceInstance;
2932             }
2933             String resourceId = newComponentInstance.getComponentUid();
2934
2935             Either<Boolean, StorageOperationStatus> componentExistsRes = toscaOperationFacade
2936                 .validateComponentExists(resourceId);
2937             if (componentExistsRes.isRight()) {
2938                 StorageOperationStatus errorStatus = componentExistsRes.right().value();
2939
2940                 log.debug("Failed to validate existing of the component {}. Status is {} ", resourceId, errorStatus);
2941                 throw new ByActionStatusComponentException(
2942                     componentsUtils.convertFromStorageResponse(errorStatus), resourceId);
2943             } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
2944                 log.debug("The resource {} not found ", resourceId);
2945                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceId);
2946             }
2947
2948             Component eitherOriginComponent = getInstanceOriginNode(currentResourceInstance);
2949             DataForMergeHolder dataHolder = compInstMergeDataBL
2950                 .saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent);
2951             ComponentInstance resResourceInfo = deleteComponentInstance(containerComponent, componentInstanceId,
2952                 containerComponentType);
2953
2954             if (resResourceInfo == null) {
2955                 log.error("Calling `deleteComponentInstance` for the resource {} returned a null", resourceId);
2956                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceId);
2957             } else {
2958                 Component origComponent = null;
2959                 OriginTypeEnum originType = currentResourceInstance.getOriginType();
2960                 newComponentInstance.setOriginType(originType);
2961                 if (originType == OriginTypeEnum.ServiceProxy) {
2962                     Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
2963                         .getLatestByName(SERVICE_PROXY, null);
2964                     if (isServiceProxyOrigin(serviceProxyOrigin)) {
2965                         throw new ByActionStatusComponentException(
2966                             componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
2967                     }
2968                     origComponent = serviceProxyOrigin.left().value();
2969
2970                     StorageOperationStatus fillProxyRes = fillInstanceData(newComponentInstance, origComponent);
2971
2972                     if (isFillProxyRes(fillProxyRes)) {
2973                         throw new ByActionStatusComponentException(
2974                             componentsUtils.convertFromStorageResponse(fillProxyRes));
2975                     }
2976                 } else if (originType == OriginTypeEnum.ServiceSubstitution) {
2977                     final Either<Component, StorageOperationStatus> getServiceResult = toscaOperationFacade
2978                         .getToscaFullElement(newComponentInstance.getComponentUid());
2979                     if (getServiceResult.isRight()) {
2980                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
2981                     }
2982                     final Component service = getServiceResult.left().value();
2983
2984                     final Either<Component, StorageOperationStatus> getServiceDerivedFromTypeResult = toscaOperationFacade
2985                         .getLatestByToscaResourceName(service.getDerivedFromGenericType(), service.getModel());
2986                     if (getServiceDerivedFromTypeResult.isRight()) {
2987                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
2988                     }
2989
2990                     origComponent = getServiceDerivedFromTypeResult.left().value();
2991
2992                     final StorageOperationStatus fillProxyRes = fillInstanceData(newComponentInstance, origComponent);
2993                     if (isFillProxyRes(fillProxyRes)) {
2994                         throw new ByActionStatusComponentException(
2995                             componentsUtils.convertFromStorageResponse(fillProxyRes));
2996                     }
2997                 } else {
2998                     origComponent = getOriginComponentFromComponentInstance(newComponentInstance);
2999                     newComponentInstance.setName(resResourceInfo.getName());
3000                     final Map<String, InterfaceDefinition> componentInterfaces = origComponent.getInterfaces();
3001                     if (MapUtils.isNotEmpty(componentInterfaces)) {
3002                         componentInterfaces.forEach(newComponentInstance::addInterface);
3003                     }
3004                 }
3005
3006                 newComponentInstance.setInvariantName(resResourceInfo.getInvariantName());
3007                 newComponentInstance.setPosX(resResourceInfo.getPosX());
3008                 newComponentInstance.setPosY(resResourceInfo.getPosY());
3009                 newComponentInstance.setDescription(resResourceInfo.getDescription());
3010                 newComponentInstance.setInstanceCount(resResourceInfo.getInstanceCount());
3011                 newComponentInstance.setMaxOccurrences(resResourceInfo.getMaxOccurrences());
3012                 newComponentInstance.setMinOccurrences(resResourceInfo.getMinOccurrences());
3013                 newComponentInstance.setDirectives(resResourceInfo.getDirectives());
3014                 checkForExternalReqAndCapabilities(origComponent, resResourceInfo);
3015
3016                 ComponentInstance updatedComponentInstance =
3017                     createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, user);
3018                 dataHolder.setCurrInstanceNode(origComponent);
3019                 compInstMergeDataBL
3020                     .mergeComponentUserOrigData(user, dataHolder, containerComponent, containerComponentId, newComponentInstance.getUniqueId());
3021
3022                 ActionStatus postChangeVersionResult = onChangeInstanceOperationOrchestrator
3023                     .doPostChangeVersionOperations(containerComponent, currentResourceInstance, newComponentInstance);
3024                 if (postChangeVersionResult != ActionStatus.OK) {
3025                     throw new ByActionStatusComponentException(postChangeVersionResult);
3026                 }
3027
3028                 ComponentParametersView filter = new ComponentParametersView(true);
3029                 filter.setIgnoreComponentInstances(false);
3030                 Either<Component, StorageOperationStatus> updatedComponentRes = toscaOperationFacade.getToscaElement(containerComponentId, filter);
3031                 if (updatedComponentRes.isRight()) {
3032                     StorageOperationStatus storageOperationStatus = updatedComponentRes.right().value();
3033                     ActionStatus actionStatus = componentsUtils
3034                         .convertFromStorageResponse(storageOperationStatus, containerComponent.getComponentType());
3035                     log.debug("Component with id {} was not found", containerComponentId);
3036                     throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING);
3037                 }
3038
3039                 maintainNodeFilters(currentResourceInstance, newComponentInstance, containerComponentId);
3040
3041                 resourceInstanceStatus = getResourceInstanceById(updatedComponentRes.left().value(),
3042                     updatedComponentInstance.getUniqueId());
3043                 if (resourceInstanceStatus.isRight()) {
3044                     throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse
3045                         (resourceInstanceStatus.right().value()), updatedComponentInstance.getUniqueId());
3046                 }
3047                 return resourceInstanceStatus.left().value();
3048             }
3049         } catch (ComponentException e) {
3050             failed = true;
3051             throw e;
3052         } finally {
3053             unlockComponent(failed, containerComponent);
3054         }
3055     }
3056
3057     private void maintainNodeFilters(
3058             ComponentInstance currentResourceInstance,
3059             ComponentInstance newComponentInstance,
3060             String containerComponentId) {
3061         CINodeFilterDataDefinition filterToMaintain = currentResourceInstance.getNodeFilter();
3062         if (null != filterToMaintain) {
3063             nodeFilterOperation.addNodeFilterData(
3064                     containerComponentId.toLowerCase(),
3065                     newComponentInstance.getUniqueId(),
3066                     filterToMaintain);
3067         }
3068     }
3069
3070     private void checkForExternalReqAndCapabilities(Component component, ComponentInstance resResourceInfo) {
3071         if (MapUtils.isNotEmpty(component.getRequirements())) {
3072             component.getRequirements().entrySet().forEach(requirementsMap -> {
3073                 if (MapUtils.isNotEmpty(resResourceInfo.getRequirements()) && resResourceInfo.getRequirements().containsKey(requirementsMap.getKey())) {
3074                     List<RequirementDefinition> resourceReqList = resResourceInfo.getRequirements().get(requirementsMap.getKey());
3075                     for (RequirementDefinition requirements : requirementsMap.getValue()) {
3076                         String requirementName = requirements.getName();
3077                         resourceReqList.forEach(requirementDefinition -> {
3078                             if (requirementName.equals(requirementDefinition.getName()) && requirementDefinition.isExternal()) {
3079                                 requirements.setExternal(requirementDefinition.isExternal());
3080                             }
3081                         });
3082                     }
3083                 }
3084             });
3085         }
3086         if (MapUtils.isNotEmpty(component.getCapabilities())) {
3087             component.getCapabilities().entrySet().forEach(capabilityMap -> {
3088                 if (MapUtils.isNotEmpty(resResourceInfo.getCapabilities()) && resResourceInfo.getCapabilities().containsKey(capabilityMap.getKey())) {
3089                     List<CapabilityDefinition> resourceCapList = resResourceInfo.getCapabilities().get(capabilityMap.getKey());
3090                     capabilityMap.getValue().forEach(capabilities -> {
3091                         String capabilityName = capabilities.getName();
3092                         for (CapabilityDefinition capDef : resourceCapList) {
3093                             if (capabilityName.equals(capDef.getName()) && capDef.isExternal()) {
3094                                 capabilities.setExternal(capDef.isExternal());
3095                             }
3096                         }
3097                     });
3098                 }
3099             });
3100         }
3101     }
3102
3103     private boolean isFillProxyRes(StorageOperationStatus fillProxyRes) {
3104         if (fillProxyRes != StorageOperationStatus.OK) {
3105             log.debug("Failed to fill service proxy resource data with data from service, error {}", fillProxyRes);
3106             return true;
3107         }
3108         return false;
3109     }
3110
3111     // US831698
3112     public List<ComponentInstanceProperty> getComponentInstancePropertiesById(String containerComponentTypeParam, String containerComponentId,
3113                                                                               String componentInstanceUniqueId, String userId) {
3114         Component containerComponent = null;
3115
3116         boolean failed = false;
3117         try {
3118             validateUserExists(userId);
3119             validateComponentType(containerComponentTypeParam);
3120
3121             Either<Component, StorageOperationStatus> validateContainerComponentExists = toscaOperationFacade.getToscaElement(containerComponentId);
3122             if (validateContainerComponentExists.isRight()) {
3123                 throw new ByActionStatusComponentException(
3124                     componentsUtils.convertFromStorageResponse(validateContainerComponentExists.right().value()));
3125             }
3126             containerComponent = validateContainerComponentExists.left().value();
3127
3128             Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3129                 componentInstanceUniqueId);
3130             if (resourceInstanceStatus.isRight()) {
3131                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId,
3132                     containerComponentId);
3133             }
3134
3135             List<ComponentInstanceProperty> instanceProperties = new ArrayList<>();
3136             if (MapUtils.isNotEmpty(containerComponent.getComponentInstancesProperties())) {
3137                 instanceProperties = containerComponent.getComponentInstancesProperties()
3138                     .get(componentInstanceUniqueId);
3139             }
3140             return instanceProperties;
3141         } catch (ComponentException e) {
3142             failed = true;
3143             throw e;
3144         } finally {
3145             unlockComponent(failed, containerComponent);
3146         }
3147     }
3148
3149     public List<ComponentInstanceAttribute> getComponentInstanceAttributesById(final String containerComponentTypeParam,
3150                                                                                final String containerComponentId,
3151                                                                                final String componentInstanceUniqueId,
3152                                                                                final String userId) {
3153         Component containerComponent = null;
3154
3155         boolean failed = false;
3156         try {
3157             validateUserExists(userId);
3158             validateComponentType(containerComponentTypeParam);
3159
3160             final Either<Component, StorageOperationStatus> validateContainerComponentExists =
3161                 toscaOperationFacade.getToscaElement(containerComponentId);
3162             if (validateContainerComponentExists.isRight()) {
3163                 throw new ByActionStatusComponentException(
3164                     componentsUtils.convertFromStorageResponse(validateContainerComponentExists.right().value()));
3165             }
3166             containerComponent = validateContainerComponentExists.left().value();
3167
3168             if (getResourceInstanceById(containerComponent, componentInstanceUniqueId).isRight()) {
3169                 throw new ByActionStatusComponentException(
3170                     ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId);
3171             }
3172
3173             final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = containerComponent.getComponentInstancesAttributes();
3174             return componentInstancesAttributes == null ? new ArrayList<>()
3175                 : componentInstancesAttributes.getOrDefault(componentInstanceUniqueId, new ArrayList<>());
3176         } catch (final ComponentException e) {
3177             failed = true;
3178             throw e;
3179         } finally {
3180             unlockComponent(failed, containerComponent);
3181         }
3182     }
3183
3184     protected void validateIncrementCounter(String resourceInstanceId, GraphPropertiesDictionary counterType,
3185                                             Wrapper<Integer> instaceCounterWrapper,
3186                                             Wrapper<ResponseFormat> errorWrapper) {
3187         Either<Integer, StorageOperationStatus> counterRes = componentInstanceOperation
3188             .increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, counterType, true);
3189
3190         if (counterRes.isRight()) {
3191             log.debug("increase And Get {} failed resource instance {}", counterType, resourceInstanceId);
3192             StorageOperationStatus status = counterRes.right().value();
3193             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3194             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus));
3195         } else {
3196             instaceCounterWrapper.setInnerElement(counterRes.left().value());
3197         }
3198
3199     }
3200
3201     /**
3202      * updates componentInstance modificationTime
3203      *
3204      * @param componentInstance
3205      * @param componentInstanceType
3206      * @param modificationTime
3207      * @param inTransaction
3208      * @return
3209      */
3210     public Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceModificationTimeAndCustomizationUuid(
3211         ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction) {
3212         Either<ComponentInstanceData, ResponseFormat> result;
3213         Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceRes = componentInstanceOperation
3214             .updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(componentInstance, componentInstanceType, modificationTime,
3215                 inTransaction);
3216         if (updateComponentInstanceRes.isRight()) {
3217             log.debug("Failed to update component instance {} with new last update date and mofifier. Status is {}. ", componentInstance.getName(),
3218                 updateComponentInstanceRes.right().value());
3219             result = Either
3220                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateComponentInstanceRes.right().value())));
3221         } else {
3222             result = Either.left(updateComponentInstanceRes.left().value());
3223         }
3224         return result;
3225     }
3226
3227     public Either<ComponentInstance, ResponseFormat> deleteServiceProxy() {
3228         // TODO Add implementation
3229         return Either.left(new ComponentInstance());
3230     }
3231
3232     public Either<ComponentInstance, ResponseFormat> createServiceProxy() {
3233         // TODO Add implementation
3234         return Either.left(new ComponentInstance());
3235     }
3236
3237     public Either<ComponentInstance, ResponseFormat> changeServiceProxyVersion() {
3238         // TODO Add implementation
3239         return Either.left(new ComponentInstance());
3240     }
3241
3242     private Boolean validateInstanceNameUniquenessUponUpdate(Component containerComponent, ComponentInstance oldComponentInstance,
3243                                                              String newInstanceName) {
3244         return ComponentValidations.validateNameIsUniqueInComponent(oldComponentInstance.getName(), newInstanceName, containerComponent);
3245     }
3246
3247     private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(final Component containerComponent, final String instanceId) {
3248         final List<ComponentInstance> instances = containerComponent.getComponentInstances();
3249         if (CollectionUtils.isEmpty(instances)) {
3250             return Either.right(StorageOperationStatus.NOT_FOUND);
3251         }
3252
3253         final Optional<ComponentInstance> foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
3254         if (foundInstance.isEmpty()) {
3255             return Either.right(StorageOperationStatus.NOT_FOUND);
3256         }
3257
3258         return Either.left(foundInstance.get());
3259     }
3260
3261     private ComponentInstance buildComponentInstance(ComponentInstance resourceInstanceForUpdate, ComponentInstance origInstanceForUpdate) {
3262         Long creationDate = origInstanceForUpdate.getCreationTime();
3263         Long modificationTime = System.currentTimeMillis();
3264         resourceInstanceForUpdate.setCreationTime(creationDate);
3265         resourceInstanceForUpdate.setModificationTime(modificationTime);
3266         resourceInstanceForUpdate.setCustomizationUUID(origInstanceForUpdate.getCustomizationUUID());
3267         if (StringUtils.isEmpty(resourceInstanceForUpdate.getName()) && StringUtils.isNotEmpty(origInstanceForUpdate.getName())) {
3268             resourceInstanceForUpdate.setName(origInstanceForUpdate.getName());
3269         }
3270         resourceInstanceForUpdate.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(resourceInstanceForUpdate.getName()));
3271         if (StringUtils.isEmpty(resourceInstanceForUpdate.getIcon())) {
3272             resourceInstanceForUpdate.setIcon(origInstanceForUpdate.getIcon());
3273         }
3274         if (StringUtils.isEmpty(resourceInstanceForUpdate.getComponentVersion())) {
3275             resourceInstanceForUpdate.setComponentVersion(origInstanceForUpdate.getComponentVersion());
3276         }
3277         if (StringUtils.isEmpty(resourceInstanceForUpdate.getComponentName())) {
3278             resourceInstanceForUpdate.setComponentName(origInstanceForUpdate.getComponentName());
3279         }
3280         if (StringUtils.isEmpty(resourceInstanceForUpdate.getToscaComponentName())) {
3281             resourceInstanceForUpdate.setToscaComponentName(origInstanceForUpdate.getToscaComponentName());
3282         }
3283         if (resourceInstanceForUpdate.getOriginType() == null) {
3284             resourceInstanceForUpdate.setOriginType(origInstanceForUpdate.getOriginType());
3285         }
3286         if (resourceInstanceForUpdate.getOriginType() == OriginTypeEnum.ServiceProxy) {
3287             resourceInstanceForUpdate.setIsProxy(true);
3288         }
3289         if (resourceInstanceForUpdate.getSourceModelInvariant() == null) {
3290             resourceInstanceForUpdate.setSourceModelInvariant(origInstanceForUpdate.getSourceModelInvariant());
3291         }
3292         if (resourceInstanceForUpdate.getSourceModelName() == null) {
3293             resourceInstanceForUpdate.setSourceModelName(origInstanceForUpdate.getSourceModelName());
3294         }
3295         if (resourceInstanceForUpdate.getSourceModelUuid() == null) {
3296             resourceInstanceForUpdate.setSourceModelUuid(origInstanceForUpdate.getSourceModelUuid());
3297         }
3298         if (resourceInstanceForUpdate.getSourceModelUid() == null) {
3299             resourceInstanceForUpdate.setSourceModelUid(origInstanceForUpdate.getSourceModelUid());
3300         }
3301         if (resourceInstanceForUpdate.getCreatedFrom() == null) {
3302             resourceInstanceForUpdate.setCreatedFrom(origInstanceForUpdate.getCreatedFrom());
3303         }
3304         return resourceInstanceForUpdate;
3305     }
3306
3307     /**
3308      * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
3309      *
3310      * @param containerComponentType
3311      * @param containerComponentId
3312      * @param componentInstanceUniqueId
3313      * @param capabilityType
3314      * @param capabilityName
3315      * @param userId
3316      * @param ownerId
3317      * @return
3318      */
3319     public List<ComponentInstanceProperty> getComponentInstanceCapabilityPropertiesById(String containerComponentType, String containerComponentId,
3320                                                                                         String componentInstanceUniqueId, String capabilityType,
3321                                                                                         String capabilityName, String ownerId, String userId) {
3322         Component containerComponent = null;
3323         List<ComponentInstanceProperty> resultOp = null;
3324         try {
3325             validateUserExists(userId);
3326             validateComponentType(containerComponentType);
3327             containerComponent = toscaOperationFacade.getToscaFullElement(containerComponentId).left().on(this::componentException);
3328             ComponentInstance resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId).left()
3329                 .on(this::componentInstanceException);
3330             resultOp = findCapabilityOfInstance(containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, ownerId,
3331                 resourceInstanceStatus.getCapabilities());
3332         } catch (StorageException | ComponentException e) {
3333             unlockRollbackWithException(containerComponent, e);
3334         } catch (Exception e) {
3335             unlockRollbackWithException(containerComponent, new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR));
3336         }
3337         unlockWithCommit(containerComponent);
3338         return resultOp;
3339     }
3340
3341     private List<ComponentInstanceProperty> findCapabilityOfInstance(String componentId, String instanceId, String capabilityType,
3342                                                                      String capabilityName, String ownerId,
3343                                                                      Map<String, List<CapabilityDefinition>> instanceCapabilities) {
3344         CapabilityDefinition foundCapability;
3345         if (MapUtils.isNotEmpty(instanceCapabilities)) {
3346             List<CapabilityDefinition> capabilitiesPerType = instanceCapabilities.get(capabilityType);
3347             if (capabilitiesPerType != null) {
3348                 Optional<CapabilityDefinition> capabilityOpt = capabilitiesPerType.stream()
3349                     .filter(c -> c.getName().equals(capabilityName) && c.getOwnerId().equals(ownerId)).findFirst();
3350                 if (capabilityOpt.isPresent()) {
3351                     foundCapability = capabilityOpt.get();
3352                     return foundCapability.getProperties() == null ? new ArrayList<>() : foundCapability.getProperties();
3353                 }
3354             }
3355         }
3356         return fetchComponentInstanceCapabilityProperties(componentId, instanceId, capabilityType, capabilityName, ownerId);
3357     }
3358
3359     private List<ComponentInstanceProperty> fetchComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityType,
3360                                                                                        String capabilityName, String ownerId) {
3361         try {
3362             return toscaOperationFacade.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId)
3363                 .left().on(this::componentInstancePropertyListException);
3364         } catch (Exception e) {
3365             log.debug("The exception {} occurred upon the component {} instance {} capability {} properties retrieving. ", componentId, instanceId,
3366                 capabilityName, e);
3367             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3368         }
3369     }
3370
3371     public Either<RequirementDefinition, ResponseFormat> updateInstanceRequirement(ComponentTypeEnum componentTypeEnum, String containerComponentId,
3372                                                                                    String componentInstanceUniqueId,
3373                                                                                    RequirementDefinition requirementDef, String userId) {
3374         Either<RequirementDefinition, ResponseFormat> resultOp = null;
3375         validateUserExists(userId);
3376         if (componentTypeEnum == null) {
3377             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceRequirement", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3378             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3379         }
3380         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3381         if (getResourceResult.isRight()) {
3382             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3383             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3384         }
3385         Component containerComponent = getResourceResult.left().value();
3386         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3387             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3388             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3389         }
3390         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3391             componentInstanceUniqueId);
3392         if (resourceInstanceStatus.isRight()) {
3393             return Either.right(componentsUtils
3394                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3395         }
3396         // lock resource
3397         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
3398         if (lockStatus != StorageOperationStatus.OK) {
3399             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3400             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3401         }
3402         try {
3403             StorageOperationStatus updateRequirementStatus = toscaOperationFacade
3404                 .updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDef);
3405             if (updateRequirementStatus != StorageOperationStatus.OK) {
3406                 log.debug("Failed to update component instance requirement on instance {} in container {}", componentInstanceUniqueId,
3407                     containerComponentId);
3408                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateRequirementStatus)));
3409             }
3410             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3411                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3412             if (updateContainerRes.isRight()) {
3413                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3414                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3415                 return resultOp;
3416             }
3417             resultOp = Either.left(requirementDef);
3418             return resultOp;
3419         } finally {
3420             if (resultOp == null || resultOp.isRight()) {
3421                 janusGraphDao.rollback();
3422             } else {
3423                 janusGraphDao.commit();
3424             }
3425             // unlock resource
3426             graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType());
3427         }
3428     }
3429
3430     public Either<CapabilityDefinition, ResponseFormat> updateInstanceCapability(final ComponentTypeEnum containerComponentType,
3431                                                                                  final String containerComponentId,
3432                                                                                  final String componentInstanceUniqueId,
3433                                                                                  final CapabilityDefinition capabilityDefinition,
3434                                                                                  final String userId) {
3435         if (containerComponentType == null) {
3436             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceCapability", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3437             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3438         }
3439         validateUserExists(userId);
3440         final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3441         if (getResourceResult.isRight()) {
3442             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3443             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_FOUND, containerComponentId));
3444         }
3445         final Component containerComponent = getResourceResult.left().value();
3446         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3447             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3448             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3449         }
3450         final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus =
3451             getResourceInstanceById(containerComponent, componentInstanceUniqueId);
3452         if (resourceInstanceStatus.isRight()) {
3453             return Either.right(componentsUtils
3454                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3455         }
3456         // lock resource
3457         final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, containerComponentType.getNodeType());
3458         if (lockStatus != StorageOperationStatus.OK) {
3459             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3460             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3461         }
3462         var success = false;
3463         try {
3464             final CapabilityDataDefinition updatedCapabilityDefinition = toscaOperationFacade
3465                 .updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition);
3466             final Either<Component, StorageOperationStatus> updateContainerEither = toscaOperationFacade
3467                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3468             if (updateContainerEither.isRight()) {
3469                 var actionStatus = componentsUtils.convertFromStorageResponse(updateContainerEither.right().value(), containerComponentType);
3470                 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3471             }
3472             success = true;
3473             return Either.left(new CapabilityDefinition(updatedCapabilityDefinition));
3474         } catch (final BusinessException e) {
3475             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
3476                 FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
3477             throw e;
3478         } catch (final Exception e) {
3479             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
3480                 FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
3481             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
3482         } finally {
3483             if (success) {
3484                 janusGraphDao.commit();
3485             } else {
3486                 janusGraphDao.rollback();
3487             }
3488             // unlock resource
3489             graphLockOperation.unlockComponent(containerComponentId, containerComponentType.getNodeType());
3490         }
3491     }
3492
3493     public Either<List<ComponentInstanceProperty>, ResponseFormat> updateInstanceCapabilityProperties(ComponentTypeEnum componentTypeEnum,
3494                                                                                                       String containerComponentId,
3495                                                                                                       String componentInstanceUniqueId,
3496                                                                                                       String capabilityType, String capabilityName,
3497                                                                                                       List<ComponentInstanceProperty> properties,
3498                                                                                                       String userId) {
3499         Either<List<ComponentInstanceProperty>, ResponseFormat> resultOp = null;
3500         validateUserExists(userId);
3501         if (componentTypeEnum == null) {
3502             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceCapabilityProperty", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3503             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3504         }
3505         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3506         if (getResourceResult.isRight()) {
3507             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3508             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3509         }
3510         Component containerComponent = getResourceResult.left().value();
3511         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3512             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3513             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3514         }
3515         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3516             componentInstanceUniqueId);
3517         if (resourceInstanceStatus.isRight()) {
3518             return Either.right(componentsUtils
3519                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3520         }
3521         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
3522         // lock resource
3523         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
3524         if (lockStatus != StorageOperationStatus.OK) {
3525             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3526             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3527         }
3528         try {
3529             for (ComponentInstanceProperty property : properties) {
3530                 Either<String, ResponseFormat> newPropertyValueEither = validatePropertyObjectValue(property, property.getValue(), false);
3531                 newPropertyValueEither.bimap(
3532                     updatedValue -> updateCapabilityPropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance,
3533                         capabilityType, capabilityName), Either::right);
3534             }
3535             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3536                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3537             if (updateContainerRes.isRight()) {
3538                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3539                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3540                 return resultOp;
3541             }
3542             resultOp = Either.left(properties);
3543             return resultOp;
3544         } finally {
3545             if (resultOp == null || resultOp.isRight()) {
3546                 janusGraphDao.rollback();
3547             } else {
3548                 janusGraphDao.commit();
3549             }
3550             // unlock resource
3551             graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType());
3552         }
3553     }
3554
3555     public Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance(ComponentInstance inputComponentInstance,
3556                                                                                         String containerComponentId, String componentInstanceId,
3557                                                                                         String userId) {
3558         Map<String, ComponentInstance> resultMap = new HashMap<>();
3559         Either<Component, StorageOperationStatus> getOrigComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3560         if (getOrigComponent.isRight()) {
3561             log.error("Failed to get the original component information");
3562             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3563         }
3564         Component origComponent = getOrigComponent.left().value();
3565         try {
3566             lockComponent(origComponent, "copyComponentInstance");
3567         } catch (ComponentException e) {
3568             log.error("destComponentInstance's data is {}", origComponent.toString());
3569             return Either.right(componentsUtils
3570                 .getResponseFormat(ActionStatus.USER_DEFINED, "Failed to lock component destComponentInstance's data is {}",
3571                     origComponent.toString()));
3572         }
3573         boolean failed = false;
3574         ComponentInstance actionResponse = null;
3575         try {
3576             actionResponse = createComponentInstance("services", containerComponentId, userId, inputComponentInstance, false);
3577         } catch (ComponentException e) {
3578             failed = true;
3579             // on failure of the create instance unlock the resource and rollback the transaction.
3580             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3581         } finally {
3582             // on failure of the create instance unlock the resource and rollback the transaction.
3583             if (null == actionResponse) {
3584                 log.error(FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS);
3585                 unlockComponent(failed, origComponent);
3586             }
3587         }
3588         Either<String, ResponseFormat> resultOp = null;
3589         try {
3590             ComponentInstance destComponentInstance = actionResponse;
3591             log.debug("destComponentInstance's data is {}", destComponentInstance);
3592             resultOp = deepCopyComponentInstance(origComponent, containerComponentId, componentInstanceId, destComponentInstance, userId);
3593             resultMap.put("componentInstance", destComponentInstance);
3594         } finally {
3595             // unlock resource
3596             if (resultOp == null || resultOp.isRight()) {
3597                 unlockComponent(true, origComponent);
3598                 janusGraphDao.rollback();
3599                 log.error("Failed to deep copy component instance");
3600             } else {
3601                 unlockComponent(false, origComponent);
3602                 janusGraphDao.commit();
3603                 log.debug("Success trasaction commit");
3604             }
3605         }
3606         if (resultOp == null || resultOp.isRight()) {
3607             return Either
3608                 .right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, "Failed to deep copy the component instance to the canvas"));
3609         } else {
3610             return Either.left(resultMap);
3611         }
3612     }
3613
3614     private Either<String, ResponseFormat> deepCopyComponentInstance(Component sourceComponent, String containerComponentId,
3615                                                                      String sourceComponentInstanceId, ComponentInstance destComponentInstance,
3616                                                                      String userId) {
3617         Either<Component, StorageOperationStatus> getDestComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3618         if (getDestComponent.isRight()) {
3619             log.error("Failed to get the dest component information");
3620             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3621         }
3622         Component destComponent = getDestComponent.left().value();
3623         Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs = copyComponentInstanceWithPropertiesAndInputs(sourceComponent,
3624             destComponent, sourceComponentInstanceId, destComponentInstance);
3625         if (copyComponentInstanceWithPropertiesAndInputs.isRight()) {
3626             log.error("Failed to copy component instance with properties and inputs as part of deep copy");
3627             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED,
3628                 "Failed to copy the component instance with properties and inputs as part of deep copy"));
3629         }
3630         Either<String, ResponseFormat> copyComponentInstanceWithAttributes = copyComponentInstanceWithAttributes(sourceComponent, destComponent,
3631             sourceComponentInstanceId, destComponentInstance, userId);
3632         if (copyComponentInstanceWithAttributes.isRight()) {
3633             log.error("Failed to copy component instance with attributes as part of deep copy");
3634             return Either.right(componentsUtils
3635                 .getResponseFormat(ActionStatus.USER_DEFINED, "Failed to copy the component instance with attributes as part of deep copy"));
3636         }
3637         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3638     }
3639
3640     private Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs(Component sourceComponent, Component destComponent,
3641                                                                                         String sourceComponentInstanceId,
3642                                                                                         ComponentInstance destComponentInstance) {
3643         log.debug("start to copy ComponentInstance with properties and inputs");
3644         List<ComponentInstanceProperty> sourcePropList = null;
3645         if (sourceComponent.getComponentInstancesProperties() != null
3646             && sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId) != null) {
3647             sourcePropList = sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId);
3648             log.debug("sourcePropList");
3649         }
3650         List<ComponentInstanceProperty> destPropList = null;
3651         String destComponentInstanceId = destComponentInstance.getUniqueId();
3652         log.debug("destComponentInstanceId: {}", destComponentInstance.getUniqueId());
3653         if (destComponent.getComponentInstancesProperties() != null
3654             && destComponent.getComponentInstancesProperties().get(destComponentInstanceId) != null) {
3655             destPropList = destComponent.getComponentInstancesProperties().get(destComponentInstanceId);
3656             log.debug("destPropList {}");
3657         }
3658         List<ComponentInstancePropInput> componentInstancePropInputList = new ArrayList<>();
3659         if (null != destPropList && null != sourcePropList) {
3660             log.debug("start to set property and attribute");
3661             for (ComponentInstanceProperty destProp : destPropList) {
3662                 String destPropertyName = destProp.getName();
3663                 for (ComponentInstanceProperty sourceProp : sourcePropList) {
3664                     if (!destPropertyName.equals(sourceProp.getName())) {
3665                         continue;
3666                     }
3667                     log.debug("now set property");
3668                     final List<GetInputValueDataDefinition> getInputValues = sourceProp.getGetInputValues();
3669                     if (getInputValues == null && !StringUtils.isEmpty(sourceProp.getValue()) && (destProp.getValue() == null || !destProp.getValue()
3670                         .equals(sourceProp.getValue()))) {
3671                         log.debug("Now starting to copy the property {} in value {}", destPropertyName, sourceProp.getValue());
3672                         destProp.setValue(sourceProp.getValue());
3673                         Either<String, ResponseFormat> updatePropertyValueEither = updateComponentInstanceProperty(destComponent.getUniqueId(),
3674                             destComponentInstanceId, destProp);
3675                         if (updatePropertyValueEither.isRight()) {
3676                             log.error("Failed to copy the property {}", destPropertyName);
3677                             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
3678                                 "Failed to paste component instance to the canvas, property copy"));
3679                         }
3680                         break;
3681                     }
3682                     log.debug("Now start to update inputs");
3683                     if (getInputValues != null) {
3684                         if (getInputValues.isEmpty()) {
3685                             log.debug("property is return from input, set by man");
3686                             break;
3687                         }
3688                         log.debug("Now starting to copy the {} property", destPropertyName);
3689                         Either<String, ResponseFormat> getSourceInputDefaultValue = getInputListDefaultValue(sourceComponent,
3690                             getInputValues.get(0).getInputId());
3691                         if (getSourceInputDefaultValue.isRight()) {
3692                             return Either.right(getSourceInputDefaultValue.right().value());
3693                         }
3694                         componentInstancePropInputList.add(new ComponentInstancePropInput(destProp));
3695                     }
3696                 }
3697             }
3698         }
3699         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3700     }
3701
3702     private Either<String, ResponseFormat> copyComponentInstanceWithAttributes(Component sourceComponent, Component destComponent,
3703                                                                                String sourceComponentInstanceId,
3704                                                                                ComponentInstance destComponentInstance, String userId) {
3705         String destComponentInstanceId = destComponentInstance.getUniqueId();
3706         log.info("start to copy component instance with attributes");
3707         List<ComponentInstanceAttribute> sourceAttributeList = null;
3708         if (sourceComponent.getComponentInstancesAttributes() != null
3709             && sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId) != null) {
3710             sourceAttributeList = sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId);
3711             log.info("sourceAttributes {}");
3712         }
3713         List<ComponentInstanceAttribute> destAttributeList = null;
3714         if (destComponent.getComponentInstancesAttributes() != null
3715             && destComponent.getComponentInstancesAttributes().get(destComponentInstanceId) != null) {
3716             destAttributeList = destComponent.getComponentInstancesAttributes().get(destComponentInstanceId);
3717             log.info("destAttributeList {}");
3718         }
3719         if (null != sourceAttributeList && null != destAttributeList) {
3720             log.info("set attribute");
3721             for (ComponentInstanceAttribute sourceAttribute : sourceAttributeList) {
3722                 String sourceAttributeName = sourceAttribute.getName();
3723                 for (ComponentInstanceAttribute destAttribute : destAttributeList) {
3724                     if (sourceAttributeName.equals(destAttribute.getName())) {
3725                         log.debug("Start to copy the attribute exists {}", sourceAttributeName);
3726                         sourceAttribute.setUniqueId(
3727                             UniqueIdBuilder.buildResourceInstanceUniqueId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName));
3728                         Either<ComponentInstanceAttribute, ResponseFormat> updateAttributeValueEither = createOrUpdateAttributeValueForCopyPaste(
3729                             ComponentTypeEnum.SERVICE, destComponent.getUniqueId(), destComponentInstanceId, sourceAttribute, userId);
3730                         if (updateAttributeValueEither.isRight()) {
3731                             log.error("Failed to copy the attribute");
3732                             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
3733                                 "Failed to paste component instance to the canvas, attribute copy"));
3734                         }
3735                         break;
3736                     }
3737                 }
3738             }
3739         }
3740         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3741     }
3742
3743     private Either<ComponentInstanceAttribute, ResponseFormat> createOrUpdateAttributeValueForCopyPaste(ComponentTypeEnum componentTypeEnum,
3744                                                                                                         String componentId, String resourceInstanceId,
3745                                                                                                         ComponentInstanceAttribute attribute,
3746                                                                                                         String userId) {
3747         Either<ComponentInstanceAttribute, ResponseFormat> resultOp = null;
3748         validateUserExists(userId);
3749         if (componentTypeEnum == null) {
3750             BeEcompErrorManager.getInstance()
3751                 .logInvalidInputError("createOrUpdateAttributeValueForCopyPaste", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3752             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3753             return resultOp;
3754         }
3755         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
3756         if (getResourceResult.isRight()) {
3757             log.info("Failed to retrieve component id {}", componentId);
3758             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3759             return resultOp;
3760         }
3761         Component containerComponent = getResourceResult.left().value();
3762         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
3763         if (resourceInstanceStatus.isRight()) {
3764             resultOp = Either
3765                 .right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, resourceInstanceId, componentId));
3766             return resultOp;
3767         }
3768         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
3769         String propertyType = attribute.getType();
3770         ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
3771         log.info("The type of attribute id{},is {} ", attribute.getUniqueId(), propertyType);
3772         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
3773             SchemaDefinition def = attribute.getSchema();
3774             if (def == null) {
3775                 log.info("Schema doesn't exists for attribute of type {}", type);
3776                 return Either
3777                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
3778             }
3779             PropertyDataDefinition propDef = def.getProperty();
3780             if (propDef == null) {
3781                 log.info("Attribute in Schema Definition inside attribute of type {} doesn't exist", type);
3782                 return Either
3783                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
3784             }
3785         }
3786         List<ComponentInstanceAttribute> instanceAttributes = containerComponent.getComponentInstancesAttributes().get(resourceInstanceId);
3787         Optional<ComponentInstanceAttribute> instanceAttribute = instanceAttributes.stream()
3788             .filter(p -> p.getUniqueId().equals(attribute.getUniqueId())).findAny();
3789         StorageOperationStatus status;
3790         if (instanceAttribute.isPresent()) {
3791             log.info("updateComponentInstanceAttribute");
3792             status = toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute);
3793         } else {
3794             log.info("addComponentInstanceAttribute");
3795             status = toscaOperationFacade.addComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute);
3796         }
3797         if (status != StorageOperationStatus.OK) {
3798             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3799             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3800             return resultOp;
3801         }
3802         List<String> path = new ArrayList<>();
3803         path.add(foundResourceInstance.getUniqueId());
3804         attribute.setPath(path);
3805         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
3806         Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3807             .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3808         if (updateContainerRes.isRight()) {
3809             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3810             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3811             return resultOp;
3812         }
3813         resultOp = Either.left(attribute);
3814         return resultOp;
3815     }
3816
3817     private Either<String, ResponseFormat> updateComponentInstanceProperty(String containerComponentId, String componentInstanceId,
3818                                                                            ComponentInstanceProperty property) {
3819         Either<String, ResponseFormat> resultOp;
3820         Either<Component, StorageOperationStatus> getComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3821         if (getComponent.isRight()) {
3822             log.error("Failed to get the component information");
3823             return Either.right(componentsUtils
3824                 .getResponseFormatForResourceInstanceProperty(ActionStatus.INVALID_CONTENT_PARAM, "Failed to get the component information"));
3825         }
3826         Component containerComponent = getComponent.left().value();
3827         StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
3828         if (status != StorageOperationStatus.OK) {
3829             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3830             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3831             return resultOp;
3832         }
3833         Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3834             .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3835         if (updateContainerRes.isRight()) {
3836             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3837             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3838             return resultOp;
3839         }
3840         return Either.left("Update OK");
3841     }
3842
3843     private Either<String, ResponseFormat> getInputListDefaultValue(Component component, String inputId) {
3844         List<InputDefinition> inputList = component.getInputs();
3845         for (InputDefinition input : inputList) {
3846             if (input.getUniqueId().equals(inputId)) {
3847                 if (input.getDefaultValue() == null) {
3848                     log.debug("The input's default value is null");
3849                     return Either.left(null);
3850                 }
3851                 return Either.left(input.getDefaultValue());
3852             }
3853         }
3854         log.error("The input's default value with id {} is not found", inputId);
3855         return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, "Failed to paste component instance to the canvas"));
3856     }
3857
3858     /**
3859      * Method to delete selected nodes and edges on composition page
3860      *
3861      * @param containerComponentType
3862      * @param componentId
3863      * @param componentInstanceIdList
3864      * @param userId
3865      * @return
3866      */
3867     public Map<String, List<String>> batchDeleteComponentInstance(String containerComponentType, String componentId,
3868                                                                   List<String> componentInstanceIdList, String userId) {
3869         List<String> deleteErrorIds = new ArrayList<>();
3870         Map<String, List<String>> deleteErrorMap = new HashMap<>();
3871         validateUserExists(userId);
3872         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId,
3873             ComponentTypeEnum.findByParamName(containerComponentType), null);
3874         boolean failed = false;
3875         try {
3876             lockComponent(containerComponent, "batchDeleteComponentInstance");
3877             for (String eachInstanceId : componentInstanceIdList) {
3878                 Either<ComponentInstance, ResponseFormat> actionResponse = batchDeleteComponentInstance(containerComponent, containerComponentType,
3879                     eachInstanceId);
3880                 log.debug("batchDeleteResourceInstances actionResponse is {}", actionResponse);
3881                 if (actionResponse.isRight()) {
3882                     log.error("Failed to delete ComponentInstance [{}]", eachInstanceId);
3883                     deleteErrorIds.add(eachInstanceId);
3884                 }
3885             }
3886             //sending the ids of the error nodes that were not deleted to UI
3887             deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
3888             return deleteErrorMap;
3889         } catch (ComponentException e) {
3890             failed = true;
3891             throw e;
3892         } finally {
3893             unlockComponent(failed, containerComponent);
3894         }
3895     }
3896
3897     private Either<ComponentInstance, ResponseFormat> batchDeleteComponentInstance(Component containerComponent, String containerComponentType,
3898                                                                                    String componentInstanceId) {
3899         ComponentInstance resultOp;
3900         final ComponentTypeEnum containerComponentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
3901         try {
3902             resultOp = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentTypeEnum);
3903             log.info("Successfully deleted instance with id {}", componentInstanceId);
3904             return Either.left(resultOp);
3905         } catch (ComponentException e) {
3906             log.error("Failed to deleteComponentInstance with instanceId[{}]", componentInstanceId);
3907             return Either.right(new ResponseFormat());
3908         }
3909     }
3910
3911     public void validateUser(final String userId) {
3912         final User user = userValidations.validateUserExists(userId);
3913         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
3914     }
3915
3916     public void setCompositionBusinessLogic(CompositionBusinessLogic compositionBusinessLogic) {
3917         this.compositionBusinessLogic = compositionBusinessLogic;
3918     }
3919
3920     public void setContainerInstanceTypesData(ContainerInstanceTypesData containerInstanceTypesData) {
3921         this.containerInstanceTypesData = containerInstanceTypesData;
3922     }
3923
3924 }