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