ddbc5dc041c74fc17744ea98684fa0c99bef9746
[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     public Either<ComponentInstanceProperty, ResponseFormat> createOrUpdateAttributeValue(ComponentTypeEnum componentTypeEnum, String componentId,
1892                                                                                           String resourceInstanceId,
1893                                                                                           ComponentInstanceProperty attribute, String userId) {
1894         Either<ComponentInstanceProperty, ResponseFormat> result = null;
1895         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
1896         validateUserExists(userId);
1897         if (errorWrapper.isEmpty()) {
1898             validateComponentTypeEnum(componentTypeEnum, "CreateOrUpdateAttributeValue", errorWrapper);
1899         }
1900         if (errorWrapper.isEmpty()) {
1901             validateCanWorkOnComponent(componentId, componentTypeEnum, userId, errorWrapper);
1902         }
1903         if (errorWrapper.isEmpty()) {
1904             validateComponentLock(componentId, componentTypeEnum, errorWrapper);
1905         }
1906         try {
1907             if (errorWrapper.isEmpty()) {
1908                 final boolean isCreate = Objects.isNull(attribute.getValueUniqueUid());
1909                 if (isCreate) {
1910                     result = createAttributeValue(attribute, resourceInstanceId);
1911                 } else {
1912                     result = updateAttributeValue(attribute, resourceInstanceId);
1913                 }
1914             } else {
1915                 result = Either.right(errorWrapper.getInnerElement());
1916             }
1917             return result;
1918         } finally {
1919             if (result == null || result.isRight()) {
1920                 janusGraphDao.rollback();
1921             } else {
1922                 janusGraphDao.commit();
1923             }
1924             // unlock resource
1925             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
1926         }
1927     }
1928
1929     public Either<List<ComponentInstanceProperty>, ResponseFormat> createOrUpdatePropertiesValues(ComponentTypeEnum componentTypeEnum,
1930                                                                                                   String componentId, String resourceInstanceId,
1931                                                                                                   List<ComponentInstanceProperty> properties,
1932                                                                                                   String userId) {
1933         Either<List<ComponentInstanceProperty>, ResponseFormat> resultOp = null;
1934         /*-------------------------------Validations---------------------------------*/
1935         validateUserExists(userId);
1936
1937         if (componentTypeEnum == null) {
1938             BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertiesValues", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
1939             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
1940             return resultOp;
1941         }
1942         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1943
1944         if (getResourceResult.isRight()) {
1945             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
1946             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
1947             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
1948         }
1949         Component containerComponent = getResourceResult.left().value();
1950
1951         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
1952             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
1953                 log.info(COMPONENT_ARCHIVED, componentId);
1954                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
1955             }
1956             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
1957             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1958         }
1959
1960         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
1961         if (resourceInstanceStatus.isRight()) {
1962             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
1963                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
1964         }
1965         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
1966
1967         // Validate instance property against it's constrains
1968         Either<Boolean, ResponseFormat> constraintValidatorResponse = validatePropertyValueConstraint(properties, componentId);
1969         if (constraintValidatorResponse.isRight()) {
1970             log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value());
1971             return Either.right(constraintValidatorResponse.right().value());
1972         }
1973         // lock resource
1974         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
1975         if (lockStatus != StorageOperationStatus.OK) {
1976             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
1977             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
1978         }
1979         List<ComponentInstanceProperty> updatedProperties = new ArrayList<>();
1980         try {
1981             for (ComponentInstanceProperty property : properties) {
1982                 validateMandatoryFields(property);
1983                 validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance);
1984                 validatePropertyConstraintsNotChanged(properties, foundResourceInstance);
1985                 String propertyParentUniqueId = property.getParentUniqueId();
1986                 if (property.isToscaFunction()) {
1987                     toscaFunctionValidator.validate(property, containerComponent);
1988                     property.setValue(StringEscapeUtils.unescapeJava(property.getToscaFunction().getValue()));
1989                     if (ToscaFunctionType.GET_INPUT == property.getToscaFunction().getType()) {
1990                         property.setGetInputValues(Collections.singletonList(buildGetInputValue(property)));
1991                     }
1992                 }
1993                 if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
1994                     ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
1995                     if (ToscaPropertyType.LIST.equals(type)) {
1996                         final JSONArray jsonArray = property.getValue() == null ? new JSONArray() : new JSONArray(property.getValue());
1997                         property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
1998                             addE(jsonArray, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
1999                         });
2000                         property.setValue(jsonArray.toString());
2001                     } else {
2002                         final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
2003                         property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
2004                             addE(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
2005                         });
2006                         property.setValue(jObject.toString());
2007                     }
2008                 }
2009                 Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel());
2010                 if (updatedPropertyValue.isRight()) {
2011                     log.error("Failed to update property object value of property: {}",
2012                         property);
2013                     throw new ByResponseFormatComponentException(updatedPropertyValue.right().value());
2014                 }
2015                 Optional<CapabilityDefinition>
2016                     capPropDefinition = getPropertyCapabilityOfChildInstance(propertyParentUniqueId, foundResourceInstance.getCapabilities());
2017                 if (capPropDefinition.isPresent()) {
2018                     updatedPropertyValue
2019                         .bimap(updatedValue -> updateCapabilityPropFromUpdateInstProp(property, updatedValue,
2020                             containerComponent, foundResourceInstance, capPropDefinition.get().getType(),
2021                             capPropDefinition.get().getName()), Either::right);
2022                 } else {
2023                     updatedPropertyValue.bimap(
2024                         updatedValue -> updatePropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance),
2025                         Either::right
2026                     );
2027                     updatedProperties.add(property);
2028                 }
2029             }
2030
2031             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2032                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2033             if (updateContainerRes.isRight()) {
2034                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2035                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2036                 return resultOp;
2037             }
2038             resultOp = Either.left(updatedProperties);
2039             return resultOp;
2040
2041         } catch (final ComponentException e) {
2042             return Either.right(e.getResponseFormat());
2043         } finally {
2044             if (resultOp == null || resultOp.isRight()) {
2045                 janusGraphDao.rollback();
2046             } else {
2047                 janusGraphDao.commit();
2048             }
2049             // unlock resource
2050             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2051         }
2052     }
2053
2054     private GetInputValueDataDefinition buildGetInputValue(final ComponentInstanceProperty property) {
2055         final GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
2056         getInputValueDataDefinition.setPropName(property.getName());
2057         getInputValueDataDefinition.setInputName(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyName());
2058         getInputValueDataDefinition.setInputId(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyUniqueId());
2059         return getInputValueDataDefinition;
2060     }
2061
2062     private void addE(JSONArray jsonArray, List<String> path, String value) {
2063         Object objectForPath = jsonArray.opt(Integer.parseInt(path.get(0)));
2064         if (objectForPath == null) {
2065             if (path.size() > 1) {
2066                 if (StringUtils.isNumeric(path.get(1))) {
2067                     objectForPath = new JSONArray();
2068                 } else {
2069                     objectForPath = new JSONObject();
2070                 }
2071                 jsonArray.put(Integer.parseInt(path.get(0)), objectForPath);
2072             }
2073         }
2074
2075         if (path.size() == 1) {
2076             Object valueAsObject = new Yaml().loadAs(value, Object.class);
2077             jsonArray.put(Integer.parseInt(path.get(0)), valueAsObject);
2078         } else {
2079             if (objectForPath instanceof JSONObject) {
2080                 addE((JSONObject) objectForPath, path.subList(1, path.size()), value);
2081             } else {
2082                 addE((JSONArray) objectForPath, path.subList(1, path.size()), value);
2083             }
2084         }
2085     }
2086
2087     private void addE(JSONObject jsonObject, List<String> path, String value) {
2088
2089         Object objectForPath = null;
2090         if (jsonObject.has(path.get(0))) {
2091             objectForPath = jsonObject.get(path.get(0));
2092         } else {
2093             if (path.size() > 1 && StringUtils.isNumeric(path.get(1))) {
2094                 objectForPath = new JSONArray();
2095             } else {
2096                 objectForPath = new JSONObject();
2097             }
2098             jsonObject.put(path.get(0), objectForPath);
2099         }
2100
2101         if (path.size() == 1) {
2102             Object valueAsObject = new Yaml().loadAs(value, Object.class);
2103             jsonObject.put(path.get(0), valueAsObject);
2104         } else {
2105             if (objectForPath instanceof JSONObject) {
2106                 addE((JSONObject) objectForPath, path.subList(1, path.size()), value);
2107             } else {
2108                 addE((JSONArray) objectForPath, path.subList(1, path.size()), value);
2109             }
2110         }
2111     }
2112
2113     private void setJsonObjectForSubProperty(final JSONObject jObject, final List<String> path, String value) {
2114         if (path.size() == 1) {
2115             Object valueAsObject = new Yaml().loadAs(value, Object.class);
2116             jObject.put(path.get(0), valueAsObject);
2117         } else {
2118             if (!jObject.has(path.get(0))) {
2119                 jObject.put(path.get(0), new JSONObject());
2120             }
2121             final JSONObject jsonObject = jObject.getJSONObject(path.get(0));
2122             setJsonObjectForSubProperty(jsonObject, path.subList(1, path.size()), value);
2123         }
2124     }
2125
2126     public Either<List<ComponentInstanceAttribute>, ResponseFormat> createOrUpdateAttributeValues(final ComponentTypeEnum componentTypeEnum,
2127                                                                                                   final String componentId,
2128                                                                                                   final String resourceInstanceId,
2129                                                                                                   final List<ComponentInstanceAttribute> attributes,
2130                                                                                                   final String userId) {
2131         Either<List<ComponentInstanceAttribute>, ResponseFormat> resultOp = null;
2132         /*-------------------------------Validations---------------------------------*/
2133         validateUserExists(userId);
2134
2135         if (componentTypeEnum == null) {
2136             BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertiesValues", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2137             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2138             return resultOp;
2139         }
2140         final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade
2141             .getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2142
2143         if (getResourceResult.isRight()) {
2144             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
2145             final ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
2146             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
2147         }
2148         final Component containerComponent = getResourceResult.left().value();
2149
2150         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
2151             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
2152                 log.info(COMPONENT_ARCHIVED, componentId);
2153                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
2154             }
2155             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
2156             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2157         }
2158
2159         final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
2160             resourceInstanceId);
2161         if (resourceInstanceStatus.isRight()) {
2162             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
2163                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
2164         }
2165         final ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
2166
2167         // Validate instance attributes against it's constraints
2168         List<PropertyDefinition> attributesToValidate = new ArrayList<>();
2169         attributes.forEach((componentInstanceAttribute) -> {
2170             PropertyDefinition propertyDefinition = new PropertyDefinition();
2171             propertyDefinition.setValue(componentInstanceAttribute.getValue());
2172             propertyDefinition.setType(componentInstanceAttribute.getType());
2173             propertyDefinition.setName(componentInstanceAttribute.getName());
2174             propertyDefinition.setUniqueId(componentInstanceAttribute.getUniqueId());
2175             attributesToValidate.add(propertyDefinition);
2176         });
2177         Either<Boolean, ResponseFormat> constraintValidatorResponse = validatePropertyValueConstraint(attributesToValidate, componentId);
2178         if (constraintValidatorResponse.isRight()) {
2179             log.error("Failed validation value and constraint of attribute: {}", constraintValidatorResponse.right().value());
2180             return Either.right(constraintValidatorResponse.right().value());
2181         }
2182
2183         // lock resource
2184         final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2185         if (lockStatus != StorageOperationStatus.OK) {
2186             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2187             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2188         }
2189         final List<ComponentInstanceAttribute> updatedProperties = new ArrayList<>();
2190         try {
2191             for (final ComponentInstanceAttribute attribute : attributes) {
2192                 final ComponentInstanceAttribute componentInstanceProperty = validateAttributeExistsOnComponent(attribute, containerComponent,
2193                     foundResourceInstance);
2194                 final Either<String, ResponseFormat> updatedPropertyValue = updateAttributeObjectValue(attribute);
2195                 if (updatedPropertyValue.isRight()) {
2196                     log.error("Failed to update attribute object value of attribute: {}", attribute);
2197                     throw new ByResponseFormatComponentException(updatedPropertyValue.right().value());
2198                 }
2199                 updatedPropertyValue.bimap(
2200                     updatedValue -> {
2201                         componentInstanceProperty.setValue(updatedValue);
2202                         return updateAttributeOnContainerComponent(attribute, updatedValue,
2203                             containerComponent, foundResourceInstance);
2204                     }, Either::right);
2205                 updatedProperties.add(componentInstanceProperty);
2206             }
2207
2208             final Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2209                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2210             if (updateContainerRes.isRight()) {
2211                 final ActionStatus actionStatus = componentsUtils
2212                     .convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2213                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2214                 return resultOp;
2215             }
2216             resultOp = Either.left(updatedProperties);
2217             return resultOp;
2218
2219         } catch (final ComponentException e) {
2220             return Either.right(e.getResponseFormat());
2221         } finally {
2222             if (resultOp == null || resultOp.isRight()) {
2223                 janusGraphDao.rollback();
2224             } else {
2225                 janusGraphDao.commit();
2226             }
2227             // unlock resource
2228             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2229         }
2230     }
2231
2232     private void validateMandatoryFields(PropertyDataDefinition property) {
2233         if (StringUtils.isEmpty(property.getName())) {
2234             throw new ByActionStatusComponentException(ActionStatus.MISSING_PROPERTY_NAME);
2235         }
2236     }
2237
2238     private void validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent,
2239                                                    ComponentInstance foundResourceInstance) {
2240         List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties()
2241             .get(foundResourceInstance.getUniqueId());
2242         final boolean hasProperty = instanceProperties.stream().anyMatch(p -> p.getName().equals(property.getName()));
2243         if (!hasProperty) {
2244             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, property.getName());
2245         }
2246     }
2247
2248     private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute,
2249                                                                           final Component containerComponent,
2250                                                                           final ComponentInstance foundResourceInstance) {
2251         final List<ComponentInstanceAttribute> instanceAttributes =
2252             containerComponent.getComponentInstancesAttributes().get(foundResourceInstance.getUniqueId());
2253         final List<ComponentInstanceProperty> instanceProperties =
2254             containerComponent.getComponentInstancesProperties().get(foundResourceInstance.getUniqueId());
2255         final Optional<ComponentInstanceAttribute> instanceAttribute =
2256             instanceAttributes.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
2257         final Optional<ComponentInstanceProperty> instanceProperty =
2258             instanceProperties.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
2259         if (instanceAttribute.isPresent()) {
2260             return instanceAttribute.get();
2261         }
2262         if (instanceProperty.isPresent()) {
2263             ComponentInstanceAttribute propAttribute = getComponentInstanceAttribute(instanceProperty.get());
2264             return propAttribute;
2265         }
2266         throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName());
2267     }
2268
2269     private ComponentInstanceAttribute getComponentInstanceAttribute(ComponentInstanceProperty property) {
2270         ComponentInstanceAttribute attribute = new ComponentInstanceAttribute();
2271         attribute.setParentUniqueId(property.getParentUniqueId());
2272         attribute.setName(property.getName());
2273         attribute.setOwnerId(property.getOwnerId());
2274         attribute.setType(property.getType());
2275         attribute.setSchema(property.getSchema());
2276         attribute.setUniqueId(property.getUniqueId());
2277         attribute.setValue(property.getValue());
2278         attribute.setDefaultValue(property.getDefaultValue());
2279         return attribute;
2280     }
2281
2282     private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property,
2283                                                                         String newValue, Component containerComponent,
2284                                                                         ComponentInstance foundResourceInstance,
2285                                                                         String capabilityType, String capabilityName) {
2286         String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
2287         ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
2288             foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId);
2289         if (actionStatus != null) {
2290             return actionStatus;
2291         }
2292
2293         return componentsUtils.getResponseFormat(ActionStatus.OK);
2294     }
2295
2296     private ResponseFormat updateCapabilityPropFromUpdateInstProp(ComponentInstanceProperty property,
2297                                                                   String newValue, Component containerComponent,
2298                                                                   ComponentInstance foundResourceInstance,
2299                                                                   String capabilityType, String capabilityName) {
2300         String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
2301         Either<Component, StorageOperationStatus> getComponentRes =
2302             toscaOperationFacade.getToscaFullElement(foundResourceInstance.getComponentUid());
2303         if (getComponentRes.isRight()) {
2304             return componentsUtils.getResponseFormat(getComponentRes.right().value());
2305         }
2306
2307         ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
2308             foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId);
2309         if (actionStatus != null) {
2310             return actionStatus;
2311         }
2312
2313         return componentsUtils.getResponseFormat(ActionStatus.OK);
2314     }
2315
2316     private ResponseFormat updateCapPropOnContainerComponent(ComponentInstanceProperty property, String newValue,
2317                                                              Component containerComponent,
2318                                                              ComponentInstance foundResourceInstance,
2319                                                              String capabilityType, String capabilityName,
2320                                                              String componentInstanceUniqueId) {
2321         Map<String, List<CapabilityDefinition>> capabilities =
2322             Optional.ofNullable(foundResourceInstance.getCapabilities()).orElse(Collections.emptyMap());
2323         List<CapabilityDefinition> capPerType =
2324             Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.emptyList());
2325         Optional<CapabilityDefinition> cap =
2326             capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny();
2327         if (cap.isPresent()) {
2328             List<ComponentInstanceProperty> capProperties = cap.get().getProperties();
2329             if (capProperties != null) {
2330                 Optional<ComponentInstanceProperty> instanceProperty =
2331                     capProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
2332                 StorageOperationStatus status;
2333                 if (instanceProperty.isPresent()) {
2334                     String capKey = ModelConverter
2335                         .buildCapabilityPropertyKey(foundResourceInstance.getOriginType().isAtomicType(), capabilityType, capabilityName,
2336                             componentInstanceUniqueId, cap.get());
2337                     instanceProperty.get().setValue(newValue);
2338                     List<String> path = new ArrayList<>();
2339                     path.add(componentInstanceUniqueId);
2340                     path.add(capKey);
2341                     instanceProperty.get().setPath(path);
2342                     status = toscaOperationFacade.updateComponentInstanceCapabiltyProperty(containerComponent,
2343                         componentInstanceUniqueId, capKey, instanceProperty.get());
2344                     if (status != StorageOperationStatus.OK) {
2345                         ActionStatus actionStatus =
2346                             componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2347                         return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2348
2349                     }
2350                     foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2351                 }
2352             }
2353         }
2354         return null;
2355     }
2356
2357     private ResponseFormat updatePropertyOnContainerComponent(ComponentInstanceProperty instanceProperty, String newValue,
2358                                                               Component containerComponent, ComponentInstance foundResourceInstance) {
2359         StorageOperationStatus status;
2360         instanceProperty.setValue(newValue);
2361         status = toscaOperationFacade.updateComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(), instanceProperty);
2362         if (status != StorageOperationStatus.OK) {
2363             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2364             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2365         }
2366         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2367         return componentsUtils.getResponseFormat(ActionStatus.OK);
2368     }
2369
2370     private ResponseFormat updateAttributeOnContainerComponent(final ComponentInstanceAttribute instanceAttribute,
2371                                                                final String newValue,
2372                                                                final Component containerComponent,
2373                                                                final ComponentInstance foundResourceInstance) {
2374
2375         instanceAttribute.setValue(newValue);
2376         final StorageOperationStatus status =
2377             toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), instanceAttribute);
2378         if (status != StorageOperationStatus.OK) {
2379             final ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2380             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2381         }
2382         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2383         return componentsUtils.getResponseFormat(ActionStatus.OK);
2384     }
2385
2386     private <T extends PropertyDefinition> Either<String, ResponseFormat> validatePropertyObjectValue(T property, String newValue, boolean isInput) {
2387         final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel());
2388         String propertyType = property.getType();
2389         String innerType = getInnerType(property);
2390
2391         // Specific Update Logic
2392         Either<Object, Boolean> isValid = propertyOperation
2393             .validateAndUpdatePropertyValue(property.getType(), newValue, true, innerType, allDataTypes);
2394         if (isValid.isRight()) {
2395             if (!Boolean.TRUE.equals(isValid.right().value())) {
2396                 log.error("Invalid value {} of property {} ", newValue, property.getName());
2397                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2398             }
2399         } else {
2400             Object object = isValid.left().value();
2401             if (object != null) {
2402                 newValue = object.toString();
2403             }
2404         }
2405         if (validateAndUpdateRules(property, isInput, allDataTypes, innerType, propertyType)) {
2406             return Either.right(componentsUtils.getResponseFormat(componentsUtils
2407                 .convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
2408         }
2409         return Either.left(newValue);
2410     }
2411
2412     private <T extends PropertyDefinition> boolean validateAndUpdateRules(T property, boolean isInput, Map<String, DataTypeDefinition> allDataTypes,
2413                                                                           String innerType, String propertyType) {
2414         if (!isInput) {
2415             ImmutablePair<String, Boolean> pair = propertyOperation
2416                 .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
2417             if (pair.getRight() != null && !pair.getRight()) {
2418                 BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
2419                 return true;
2420             }
2421         }
2422         return false;
2423     }
2424
2425     private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, final String model) {
2426         final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
2427         String innerType = null;
2428         String propertyType = property.getType();
2429         ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
2430         log.debug("The type of the property {} is {}", property.getUniqueId(), propertyType);
2431
2432         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
2433             SchemaDefinition schema = property.getSchema();
2434             if (schema == null) {
2435                 log.debug("Schema doesn't exists for property of type {}", type);
2436                 return Either
2437                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2438             }
2439             PropertyDataDefinition propDef = schema.getProperty();
2440             if (propDef == null) {
2441                 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
2442                 return Either
2443                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2444             }
2445             innerType = propDef.getType();
2446         }
2447
2448         // Specific Update Logic
2449         String newValue = property.getValue();
2450
2451         if (property.hasToscaFunction() || CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
2452             return Either.left(newValue);
2453         }
2454
2455         Either<Object, Boolean> isValid = propertyOperation
2456             .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes);
2457         if (isValid.isRight()) {
2458             if (!Boolean.TRUE.equals(isValid.right().value())) {
2459                 log.debug("validate and update property value has failed with value: {}", property.getValue());
2460                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
2461                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
2462             }
2463         } else {
2464             Object object = isValid.left().value();
2465             if (object != null) {
2466                 newValue = object.toString();
2467             }
2468         }
2469         ImmutablePair<String, Boolean> pair = propertyOperation
2470             .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
2471         if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
2472             BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
2473             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
2474                 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
2475         }
2476         return Either.left(newValue);
2477     }
2478
2479     private <T extends AttributeDefinition> Either<String, ResponseFormat> updateAttributeObjectValue(final T attribute) {
2480         String innerType = null;
2481         final String attributeType = attribute.getType();
2482         final ToscaPropertyType type = ToscaPropertyType.isValidType(attributeType);
2483         log.debug("The type of the attribute {} is {}", attribute.getUniqueId(), attributeType);
2484
2485         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
2486             final SchemaDefinition def = attribute.getSchema();
2487             if (def == null) {
2488                 log.debug("Schema doesn't exists for attribute of type {}", type);
2489                 return Either
2490                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2491             }
2492             PropertyDataDefinition propDef = def.getProperty();
2493             if (propDef == null) {
2494                 log.debug("Property in Schema Definition inside attribute of type {} doesn't exist", type);
2495                 return Either
2496                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
2497             }
2498             innerType = propDef.getType();
2499         }
2500
2501         // Specific Update Logic
2502         String newValue = attribute.getValue();
2503
2504         final var isValid = attributeOperation.validateAndUpdateAttributeValue(attribute, innerType,
2505             componentsUtils.getAllDataTypes(applicationDataTypeCache, attribute.getModel()));
2506         if (isValid.isRight()) {
2507             final Boolean res = isValid.right().value();
2508             if (!Boolean.TRUE.equals(res)) {
2509                 log.debug("validate and update attribute value has failed with value: {}", newValue);
2510                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
2511                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
2512             }
2513         } else {
2514             final Object object = isValid.left().value();
2515             if (object != null) {
2516                 newValue = object.toString();
2517             }
2518         }
2519         return Either.left(newValue);
2520     }
2521
2522     private <T extends PropertyDefinition> void validateToscaGetFunction(T property, Component parentComponent) {
2523         final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
2524         validateGetToscaFunctionAttributes(toscaGetFunction);
2525         validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource());
2526         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) {
2527             validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel());
2528             return;
2529         }
2530         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) {
2531             if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
2532                 validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel());
2533             } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
2534                 final ComponentInstance componentInstance =
2535                     parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
2536                         .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
2537                 validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel());
2538             }
2539
2540             return;
2541         }
2542         if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) {
2543             if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
2544                 validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel());
2545             } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
2546                 final ComponentInstance componentInstance =
2547                     parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
2548                         .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
2549                 validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel());
2550             }
2551
2552             return;
2553         }
2554
2555         throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get();
2556     }
2557
2558     private <T extends PropertyDefinition> void validateGetFunction(final T property,
2559                                                                     final List<? extends ToscaPropertyData> parentProperties,
2560                                                                     final String model) {
2561         final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
2562         if (CollectionUtils.isEmpty(parentProperties)) {
2563             throw ToscaGetFunctionExceptionSupplier
2564                 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(),
2565                     toscaGetFunction.getFunctionType()
2566                 ).get();
2567         }
2568         final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId();
2569         ToscaPropertyData referredProperty = parentProperties.stream()
2570             .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId()))
2571             .findFirst()
2572             .orElseThrow(ToscaGetFunctionExceptionSupplier
2573                 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource()
2574                     , toscaGetFunction.getFunctionType())
2575             );
2576         if (toscaGetFunction.isSubProperty()) {
2577             referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
2578         }
2579
2580         if (!property.getType().equals(referredProperty.getType()) && !"list".equalsIgnoreCase(referredProperty.getType())) {
2581             throw ToscaGetFunctionExceptionSupplier
2582                 .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get();
2583         }
2584         if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType())
2585             && !"list".equalsIgnoreCase(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) {
2586             throw ToscaGetFunctionExceptionSupplier
2587                 .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get();
2588         }
2589     }
2590
2591     private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty,
2592                                               final ToscaGetFunctionDataDefinition toscaGetFunction,
2593                                               final String model) {
2594         final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model);
2595         final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource();
2596         DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType());
2597         if (dataType == null) {
2598             throw ToscaGetFunctionExceptionSupplier
2599                 .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get();
2600         }
2601         ToscaPropertyData foundProperty = referredProperty;
2602         for (int i = 1; i < propertyPathFromSource.size(); i++) {
2603             final String currentPropertyName = propertyPathFromSource.get(i);
2604             foundProperty = dataType.getProperties().stream()
2605                 .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst()
2606                 .orElseThrow(
2607                     ToscaGetFunctionExceptionSupplier
2608                         .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(),
2609                             toscaGetFunction.getFunctionType())
2610                 );
2611             dataType = dataTypeMap.get(foundProperty.getType());
2612             if (dataType == null) {
2613                 throw ToscaGetFunctionExceptionSupplier
2614                     .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(),
2615                         toscaGetFunction.getFunctionType()).get();
2616             }
2617         }
2618         return foundProperty;
2619     }
2620
2621     private Map<String, DataTypeDefinition> loadDataTypes(String model) {
2622         final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither =
2623             applicationDataTypeCache.getAll(model);
2624         if (dataTypeEither.isRight()) {
2625             throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get();
2626         }
2627         return dataTypeEither.left().value();
2628     }
2629
2630     private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) {
2631         if (functionType == ToscaGetFunctionType.GET_INPUT && propertySource != PropertySource.SELF) {
2632             throw ToscaGetFunctionExceptionSupplier
2633                 .targetSourceNotSupported(functionType, propertySource).get();
2634         }
2635         if (functionType == ToscaGetFunctionType.GET_PROPERTY && !List.of(PropertySource.SELF, PropertySource.INSTANCE).contains(propertySource)) {
2636             throw ToscaGetFunctionExceptionSupplier
2637                 .targetSourceNotSupported(functionType, propertySource).get();
2638         }
2639     }
2640
2641     private void validateGetToscaFunctionAttributes(final ToscaGetFunctionDataDefinition toscaGetFunction) {
2642         if (toscaGetFunction.getFunctionType() == null) {
2643             throw ToscaGetFunctionExceptionSupplier.targetFunctionTypeNotFound().get();
2644         }
2645         if (toscaGetFunction.getPropertySource() == null) {
2646             throw ToscaGetFunctionExceptionSupplier.targetPropertySourceNotFound(toscaGetFunction.getFunctionType()).get();
2647         }
2648         if (CollectionUtils.isEmpty(toscaGetFunction.getPropertyPathFromSource())) {
2649             throw ToscaGetFunctionExceptionSupplier
2650                 .targetSourcePathNotFound(toscaGetFunction.getFunctionType()).get();
2651         }
2652         if (StringUtils.isEmpty(toscaGetFunction.getSourceName()) || StringUtils.isBlank(toscaGetFunction.getSourceName())) {
2653             throw ToscaGetFunctionExceptionSupplier.sourceNameNotFound(toscaGetFunction.getPropertySource()).get();
2654         }
2655         if (StringUtils.isEmpty(toscaGetFunction.getSourceUniqueId()) || StringUtils.isBlank(toscaGetFunction.getSourceUniqueId())) {
2656             throw ToscaGetFunctionExceptionSupplier.sourceIdNotFound(toscaGetFunction.getPropertySource()).get();
2657         }
2658         if (StringUtils.isEmpty(toscaGetFunction.getPropertyName()) || StringUtils.isBlank(toscaGetFunction.getPropertyName())) {
2659             throw ToscaGetFunctionExceptionSupplier.propertyNameNotFound(toscaGetFunction.getPropertySource()).get();
2660         }
2661         if (StringUtils.isEmpty(toscaGetFunction.getPropertyUniqueId()) || StringUtils.isBlank(toscaGetFunction.getPropertyUniqueId())) {
2662             throw ToscaGetFunctionExceptionSupplier.propertyIdNotFound(toscaGetFunction.getPropertySource()).get();
2663         }
2664     }
2665
2666     private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent,
2667                                                            ComponentInstance foundResourceInstance) {
2668         StorageOperationStatus status;
2669         input.setValue(newValue);
2670         status = toscaOperationFacade.updateComponentInstanceInput(containerComponent, foundResourceInstance.getUniqueId(), input);
2671         if (status != StorageOperationStatus.OK) {
2672             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2673             return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
2674         }
2675         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
2676         return componentsUtils.getResponseFormat(ActionStatus.OK);
2677     }
2678
2679     public Either<List<ComponentInstanceInput>, ResponseFormat> createOrUpdateInstanceInputValues(ComponentTypeEnum componentTypeEnum,
2680                                                                                                   String componentId, String resourceInstanceId,
2681                                                                                                   List<ComponentInstanceInput> inputs,
2682                                                                                                   String userId) {
2683
2684         Either<List<ComponentInstanceInput>, ResponseFormat> resultOp = null;
2685
2686         validateUserExists(userId);
2687
2688         if (componentTypeEnum == null) {
2689             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2690             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2691             return resultOp;
2692         }
2693         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2694
2695         if (getResourceResult.isRight()) {
2696             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
2697             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
2698             return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
2699         }
2700         Component containerComponent = getResourceResult.left().value();
2701
2702         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
2703             if (Boolean.TRUE.equals(containerComponent.isArchived())) {
2704                 log.info(COMPONENT_ARCHIVED, componentId);
2705                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
2706             }
2707             log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
2708             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2709             return resultOp;
2710         }
2711         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
2712         if (resourceInstanceStatus.isRight()) {
2713             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
2714                 resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
2715         }
2716
2717         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
2718
2719         // lock resource
2720         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2721         if (lockStatus != StorageOperationStatus.OK) {
2722             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2723             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2724         }
2725         List<ComponentInstanceInput> updatedInputs = new ArrayList<>();
2726         try {
2727             for (ComponentInstanceInput input : inputs) {
2728                 validateMandatoryFields(input);
2729                 ComponentInstanceInput componentInstanceInput = validateInputExistsOnComponent(input, containerComponent, foundResourceInstance);
2730                 Either<String, ResponseFormat> validatedInputValue = validatePropertyObjectValue(componentInstanceInput, input.getValue(), true);
2731                 if (validatedInputValue.isRight()) {
2732                     throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT, input.getName());
2733                 }
2734                 updateInputOnContainerComponent(componentInstanceInput, validatedInputValue.left().value(), containerComponent,
2735                     foundResourceInstance);
2736                 updatedInputs.add(componentInstanceInput);
2737             }
2738             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
2739                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
2740             if (updateContainerRes.isRight()) {
2741                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
2742                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2743                 return resultOp;
2744             }
2745             resultOp = Either.left(updatedInputs);
2746             return resultOp;
2747
2748         } finally {
2749             if (resultOp == null || resultOp.isRight()) {
2750                 janusGraphDao.rollback();
2751             } else {
2752                 janusGraphDao.commit();
2753             }
2754             // unlock resource
2755             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2756         }
2757
2758     }
2759
2760     private ComponentInstanceInput validateInputExistsOnComponent(ComponentInstanceInput input, Component containerComponent,
2761                                                                   ComponentInstance foundResourceInstance) {
2762         List<ComponentInstanceInput> instanceProperties = containerComponent.getComponentInstancesInputs().get(foundResourceInstance.getUniqueId());
2763         Optional<ComponentInstanceInput> instanceInput = instanceProperties.stream().filter(p -> p.getName().equals(input.getName())).findAny();
2764         if (!instanceInput.isPresent()) {
2765             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, input.getName());
2766         }
2767         return instanceInput.get();
2768     }
2769
2770     public Either<ComponentInstanceProperty, ResponseFormat> createOrUpdateGroupInstancePropertyValue(ComponentTypeEnum componentTypeEnum,
2771                                                                                                       String componentId, String resourceInstanceId,
2772                                                                                                       String groupInstanceId,
2773                                                                                                       ComponentInstanceProperty property,
2774                                                                                                       String userId) {
2775
2776         Either<ComponentInstanceProperty, ResponseFormat> resultOp = null;
2777
2778         validateUserExists(userId);
2779
2780         if (componentTypeEnum == null) {
2781             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2782             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2783             return resultOp;
2784         }
2785
2786         if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
2787             log.info("Restricted operation for user: {} on service: {}", userId, componentId);
2788             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2789             return resultOp;
2790         }
2791         // lock resource
2792         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
2793         if (lockStatus != StorageOperationStatus.OK) {
2794             log.debug(FAILED_TO_LOCK_SERVICE, componentId);
2795             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2796             return resultOp;
2797         }
2798         try {
2799             String propertyValueUid = property.getValueUniqueUid();
2800
2801             if (propertyValueUid == null) {
2802
2803                 Either<Integer, StorageOperationStatus> counterRes = groupInstanceOperation
2804                     .increaseAndGetGroupInstancePropertyCounter(groupInstanceId);
2805
2806                 if (counterRes.isRight()) {
2807                     log.debug("increaseAndGetResourcePropertyCounter failed resource instance: {} property: {}", resourceInstanceId, property);
2808                     StorageOperationStatus status = counterRes.right().value();
2809                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
2810                     resultOp = Either.right(componentsUtils.getResponseFormat(actionStatus));
2811                 }
2812                 Integer index = counterRes.left().value();
2813                 Either<ComponentInstanceProperty, StorageOperationStatus> result = groupInstanceOperation
2814                     .addPropertyValueToGroupInstance(property, resourceInstanceId, index, true);
2815
2816                 if (result.isLeft()) {
2817                     log.trace("Property value was added to resource instance {}", resourceInstanceId);
2818                     ComponentInstanceProperty instanceProperty = result.left().value();
2819
2820                     resultOp = Either.left(instanceProperty);
2821
2822                 } else {
2823                     log.debug("Failed to add property value: {} to resource instance {}", property, resourceInstanceId);
2824
2825                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2826
2827                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2828                 }
2829
2830             } else {
2831                 Either<ComponentInstanceProperty, StorageOperationStatus> result = groupInstanceOperation
2832                     .updatePropertyValueInGroupInstance(property, resourceInstanceId, true);
2833
2834                 if (result.isLeft()) {
2835                     log.debug("Property value {} was updated on graph.", property.getValueUniqueUid());
2836                     ComponentInstanceProperty instanceProperty = result.left().value();
2837
2838                     resultOp = Either.left(instanceProperty);
2839
2840                 } else {
2841                     log.debug("Failed to update property value: {}, in resource instance {}", property, resourceInstanceId);
2842
2843                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2844
2845                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2846                 }
2847             }
2848             if (resultOp.isLeft()) {
2849                 StorageOperationStatus updateCustomizationUUID = componentInstanceOperation.updateCustomizationUUID(resourceInstanceId);
2850                 if (updateCustomizationUUID != StorageOperationStatus.OK) {
2851                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateCustomizationUUID);
2852
2853                     resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2854
2855                 }
2856             }
2857             return resultOp;
2858
2859         } finally {
2860             if (resultOp == null || resultOp.isRight()) {
2861                 janusGraphDao.rollback();
2862             } else {
2863                 janusGraphDao.commit();
2864             }
2865             // unlock resource
2866             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
2867         }
2868
2869     }
2870
2871     public Either<ComponentInstanceProperty, ResponseFormat> deletePropertyValue(ComponentTypeEnum componentTypeEnum, String serviceId,
2872                                                                                  String resourceInstanceId, String propertyValueId, String userId) {
2873
2874         validateUserExists(userId);
2875
2876         Either<ComponentInstanceProperty, ResponseFormat> resultOp = null;
2877
2878         if (componentTypeEnum == null) {
2879             BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_OR_UPDATE_PROPERTY_VALUE, INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
2880             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
2881             return resultOp;
2882         }
2883
2884         if (!ComponentValidationUtils.canWorkOnComponent(serviceId, toscaOperationFacade, userId)) {
2885             log.info("Restricted operation for user {} on service {}", userId, serviceId);
2886             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2887             return resultOp;
2888         }
2889         // lock resource
2890         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(serviceId, componentTypeEnum.getNodeType());
2891         if (lockStatus != StorageOperationStatus.OK) {
2892             log.debug(FAILED_TO_LOCK_SERVICE, serviceId);
2893             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
2894             return resultOp;
2895         }
2896         try {
2897             Either<ComponentInstanceProperty, StorageOperationStatus> result = propertyOperation
2898                 .removePropertyValueFromResourceInstance(propertyValueId, resourceInstanceId, true);
2899
2900             if (result.isLeft()) {
2901                 log.debug("Property value {} was removed from graph.", propertyValueId);
2902                 ComponentInstanceProperty instanceProperty = result.left().value();
2903
2904                 resultOp = Either.left(instanceProperty);
2905                 return resultOp;
2906
2907             } else {
2908                 log.debug("Failed to remove property value {} in resource instance {}", propertyValueId, resourceInstanceId);
2909
2910                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value());
2911
2912                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
2913
2914                 return resultOp;
2915             }
2916
2917         } finally {
2918             if (resultOp == null || resultOp.isRight()) {
2919                 janusGraphDao.rollback();
2920             } else {
2921                 janusGraphDao.commit();
2922             }
2923             // unlock resource
2924             graphLockOperation.unlockComponent(serviceId, componentTypeEnum.getNodeType());
2925         }
2926
2927     }
2928
2929     private Component getAndValidateOriginComponentOfComponentInstance(Component containerComponent, ComponentInstance componentInstance) {
2930
2931         ComponentTypeEnum componentType = getComponentTypeByParentComponentType(containerComponent.getComponentType());
2932         Component component;
2933         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid());
2934         if (getComponentRes.isRight()) {
2935             log.debug("Failed to get the component with id {} for component instance {} creation. ", componentInstance.getComponentUid(),
2936                 componentInstance.getName());
2937             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentRes.right().value(), componentType);
2938             throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING);
2939         }
2940         component = getComponentRes.left().value();
2941         LifecycleStateEnum resourceCurrState = component.getLifecycleState();
2942         if (resourceCurrState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
2943             ActionStatus actionStatus = ActionStatus.CONTAINER_CANNOT_CONTAIN_COMPONENT_IN_STATE;
2944             throw new ByActionStatusComponentException(actionStatus, containerComponent.getComponentType().toString(), resourceCurrState.toString());
2945         }
2946         if (Boolean.TRUE.equals(component.isArchived())) {
2947             ActionStatus actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
2948             throw new ByActionStatusComponentException(actionStatus, component.getName());
2949         }
2950         final Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
2951         if (MapUtils.isNotEmpty(componentInterfaces)) {
2952             componentInterfaces.forEach(componentInstance::addInterface);
2953         }
2954         return component;
2955     }
2956
2957     public Either<Set<String>, ResponseFormat> forwardingPathOnVersionChange(String containerComponentParam,
2958                                                                              String containerComponentId,
2959                                                                              String componentInstanceId,
2960                                                                              ComponentInstance newComponentInstance) {
2961         Either<Set<String>, ResponseFormat> resultOp;
2962         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
2963         ComponentParametersView componentParametersView = getComponentParametersViewForForwardingPath();
2964
2965         //Fetch Component
2966         Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, componentParametersView);
2967
2968         //Fetch current component instance
2969         Either<ComponentInstance, StorageOperationStatus> eitherResourceInstance =
2970             getResourceInstanceById(containerComponent, componentInstanceId);
2971         if (eitherResourceInstance.isRight()) {
2972             resultOp = Either.right(componentsUtils.getResponseFormat(
2973                 ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId, containerComponentId));
2974             return resultOp;
2975         }
2976         ComponentInstance currentResourceInstance = eitherResourceInstance.left().value();
2977
2978         //Check whether new componentInstance exists
2979         String resourceId = newComponentInstance.getComponentUid();
2980         Either<Boolean, StorageOperationStatus> componentExistsRes = toscaOperationFacade.validateComponentExists(resourceId);
2981         if (componentExistsRes.isRight()) {
2982             log.debug("Failed to find resource {}", resourceId);
2983             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse
2984                 (componentExistsRes.right().value()), resourceId));
2985             return resultOp;
2986         } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
2987             log.debug("The resource {} not found ", resourceId);
2988             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
2989             return resultOp;
2990         }
2991
2992         //Fetch component using new component instance uid
2993         Component updatedContainerComponent = getOriginComponentFromComponentInstance(newComponentInstance);
2994         Set<String> toDeleteForwardingPaths = getForwardingPaths(containerComponent,
2995             currentResourceInstance, updatedContainerComponent);
2996         resultOp = Either.left(toDeleteForwardingPaths);
2997
2998         return resultOp;
2999     }
3000
3001     private Set<String> getForwardingPaths(Component containerComponent, ComponentInstance currentResourceInstance,
3002                                            Component updatedContainerComponent) {
3003         DataForMergeHolder dataForMergeHolder = new DataForMergeHolder();
3004         dataForMergeHolder.setOrigComponentInstId(currentResourceInstance.getName());
3005
3006         Service service = (Service) containerComponent;
3007         ForwardingPathUtils forwardingPathUtils = new ForwardingPathUtils();
3008
3009         return forwardingPathUtils.
3010             getForwardingPathsToBeDeletedOnVersionChange(service, dataForMergeHolder, updatedContainerComponent);
3011     }
3012
3013     private ComponentParametersView getComponentParametersViewForForwardingPath() {
3014         ComponentParametersView componentParametersView = new ComponentParametersView();
3015         componentParametersView.setIgnoreCapabiltyProperties(false);
3016         componentParametersView.setIgnoreServicePath(false);
3017         return componentParametersView;
3018     }
3019
3020     public ComponentInstance changeComponentInstanceVersion(String containerComponentParam, String containerComponentId, String componentInstanceId,
3021                                                             String userId, ComponentInstance newComponentInstance) {
3022
3023         User user = validateUserExists(userId);
3024         final ComponentTypeEnum containerComponentType = validateComponentType(containerComponentParam);
3025         ComponentParametersView componentParametersView = new ComponentParametersView();
3026         componentParametersView.setIgnoreCapabiltyProperties(false);
3027
3028         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType,
3029             componentParametersView);
3030
3031         validateCanWorkOnComponent(containerComponent, userId);
3032
3033         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceId);
3034         if (resourceInstanceStatus.isRight()) {
3035             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId,
3036                 containerComponentId);
3037         }
3038
3039         ComponentInstance currentResourceInstance = resourceInstanceStatus.left().value();
3040
3041         return changeInstanceVersion(containerComponent, currentResourceInstance, newComponentInstance, user, containerComponentType);
3042     }
3043
3044     public ComponentInstance changeInstanceVersion(org.openecomp.sdc.be.model.Component containerComponent,
3045                                                    ComponentInstance currentResourceInstance,
3046                                                    ComponentInstance newComponentInstance,
3047                                                    User user,
3048                                                    final ComponentTypeEnum containerComponentType) {
3049         boolean failed = false;
3050         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus;
3051
3052         try {
3053             lockComponent(containerComponent, "changeComponentInstanceVersion");
3054             String containerComponentId = containerComponent.getUniqueId();
3055             String componentInstanceId = currentResourceInstance.getUniqueId();
3056             if (currentResourceInstance.getComponentUid().equals(newComponentInstance.getComponentUid())) {
3057                 return currentResourceInstance;
3058             }
3059             String resourceId = newComponentInstance.getComponentUid();
3060
3061             Either<Boolean, StorageOperationStatus> componentExistsRes = toscaOperationFacade
3062                 .validateComponentExists(resourceId);
3063             if (componentExistsRes.isRight()) {
3064                 StorageOperationStatus errorStatus = componentExistsRes.right().value();
3065
3066                 log.debug("Failed to validate existing of the component {}. Status is {} ", resourceId, errorStatus);
3067                 throw new ByActionStatusComponentException(
3068                     componentsUtils.convertFromStorageResponse(errorStatus), resourceId);
3069             } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
3070                 log.debug("The resource {} not found ", resourceId);
3071                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceId);
3072             }
3073
3074             Component eitherOriginComponent = getInstanceOriginNode(currentResourceInstance);
3075             DataForMergeHolder dataHolder =
3076                 compInstMergeDataBL.saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent);
3077             ComponentInstance resResourceInfo = deleteComponentInstance(containerComponent, componentInstanceId,
3078                 containerComponentType);
3079
3080             if (resResourceInfo == null) {
3081                 log.error("Calling `deleteComponentInstance` for the resource {} returned a null", resourceId);
3082                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceId);
3083             } else {
3084                 Component origComponent = null;
3085                 OriginTypeEnum originType = currentResourceInstance.getOriginType();
3086                 newComponentInstance.setOriginType(originType);
3087                 if (originType == OriginTypeEnum.ServiceProxy) {
3088                     Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
3089                         .getLatestByName(SERVICE_PROXY, null);
3090                     if (isServiceProxyOrigin(serviceProxyOrigin)) {
3091                         throw new ByActionStatusComponentException(
3092                             componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
3093                     }
3094                     origComponent = serviceProxyOrigin.left().value();
3095
3096                     StorageOperationStatus fillProxyRes = fillInstanceData(newComponentInstance, origComponent);
3097
3098                     if (isFillProxyRes(fillProxyRes)) {
3099                         throw new ByActionStatusComponentException(
3100                             componentsUtils.convertFromStorageResponse(fillProxyRes));
3101                     }
3102                 } else if (originType == OriginTypeEnum.ServiceSubstitution) {
3103                     final Either<Component, StorageOperationStatus> getServiceResult = toscaOperationFacade
3104                         .getToscaFullElement(newComponentInstance.getComponentUid());
3105                     if (getServiceResult.isRight()) {
3106                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
3107                     }
3108                     final Component service = getServiceResult.left().value();
3109
3110                     final Either<Component, StorageOperationStatus> getServiceDerivedFromTypeResult = toscaOperationFacade
3111                         .getLatestByToscaResourceName(service.getDerivedFromGenericType(), service.getModel());
3112                     if (getServiceDerivedFromTypeResult.isRight()) {
3113                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
3114                     }
3115
3116                     origComponent = getServiceDerivedFromTypeResult.left().value();
3117
3118                     final StorageOperationStatus fillProxyRes = fillInstanceData(newComponentInstance, origComponent);
3119                     if (isFillProxyRes(fillProxyRes)) {
3120                         throw new ByActionStatusComponentException(
3121                             componentsUtils.convertFromStorageResponse(fillProxyRes));
3122                     }
3123                 } else {
3124                     origComponent = getOriginComponentFromComponentInstance(newComponentInstance);
3125                     newComponentInstance.setName(resResourceInfo.getName());
3126                     final Map<String, InterfaceDefinition> componentInterfaces = origComponent.getInterfaces();
3127                     if (MapUtils.isNotEmpty(componentInterfaces)) {
3128                         componentInterfaces.forEach(newComponentInstance::addInterface);
3129                     }
3130                 }
3131
3132                 newComponentInstance.setInvariantName(resResourceInfo.getInvariantName());
3133                 newComponentInstance.setPosX(resResourceInfo.getPosX());
3134                 newComponentInstance.setPosY(resResourceInfo.getPosY());
3135                 newComponentInstance.setDescription(resResourceInfo.getDescription());
3136                 newComponentInstance.setInstanceCount(resResourceInfo.getInstanceCount());
3137                 newComponentInstance.setMaxOccurrences(resResourceInfo.getMaxOccurrences());
3138                 newComponentInstance.setMinOccurrences(resResourceInfo.getMinOccurrences());
3139                 newComponentInstance.setDirectives(resResourceInfo.getDirectives());
3140                 checkForExternalReqAndCapabilities(origComponent, resResourceInfo);
3141
3142                 ComponentInstance updatedComponentInstance =
3143                     createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, user);
3144                 dataHolder.setCurrInstanceNode(origComponent);
3145                 compInstMergeDataBL
3146                     .mergeComponentUserOrigData(user, dataHolder, containerComponent, containerComponentId, newComponentInstance.getUniqueId());
3147
3148                 ActionStatus postChangeVersionResult = onChangeInstanceOperationOrchestrator
3149                     .doPostChangeVersionOperations(containerComponent, currentResourceInstance, newComponentInstance);
3150                 if (postChangeVersionResult != ActionStatus.OK) {
3151                     throw new ByActionStatusComponentException(postChangeVersionResult);
3152                 }
3153
3154                 ComponentParametersView filter = new ComponentParametersView(true);
3155                 filter.setIgnoreComponentInstances(false);
3156                 Either<Component, StorageOperationStatus> updatedComponentRes = toscaOperationFacade.getToscaElement(containerComponentId, filter);
3157                 if (updatedComponentRes.isRight()) {
3158                     StorageOperationStatus storageOperationStatus = updatedComponentRes.right().value();
3159                     ActionStatus actionStatus = componentsUtils
3160                         .convertFromStorageResponse(storageOperationStatus, containerComponent.getComponentType());
3161                     log.debug("Component with id {} was not found", containerComponentId);
3162                     throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING);
3163                 }
3164
3165                 maintainNodeFilters(currentResourceInstance, newComponentInstance, containerComponentId);
3166
3167                 resourceInstanceStatus = getResourceInstanceById(updatedComponentRes.left().value(), updatedComponentInstance.getUniqueId());
3168                 if (resourceInstanceStatus.isRight()) {
3169                     throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse
3170                         (resourceInstanceStatus.right().value()), updatedComponentInstance.getUniqueId());
3171                 }
3172                 return resourceInstanceStatus.left().value();
3173             }
3174         } catch (ComponentException e) {
3175             failed = true;
3176             throw e;
3177         } finally {
3178             unlockComponent(failed, containerComponent);
3179         }
3180     }
3181
3182     private void maintainNodeFilters(
3183         ComponentInstance currentResourceInstance,
3184         ComponentInstance newComponentInstance,
3185         String containerComponentId) {
3186         CINodeFilterDataDefinition filterToMaintain = currentResourceInstance.getNodeFilter();
3187         if (null != filterToMaintain) {
3188             nodeFilterOperation.addNodeFilterData(
3189                 containerComponentId.toLowerCase(),
3190                 newComponentInstance.getUniqueId(),
3191                 filterToMaintain);
3192         }
3193     }
3194
3195     private void checkForExternalReqAndCapabilities(Component component, ComponentInstance resResourceInfo) {
3196         if (MapUtils.isNotEmpty(component.getRequirements())) {
3197             component.getRequirements().entrySet().forEach(requirementsMap -> {
3198                 if (MapUtils.isNotEmpty(resResourceInfo.getRequirements()) &&
3199                     resResourceInfo.getRequirements().containsKey(requirementsMap.getKey())) {
3200                     List<RequirementDefinition> resourceReqList = resResourceInfo.getRequirements().get(requirementsMap.getKey());
3201                     for (RequirementDefinition requirements : requirementsMap.getValue()) {
3202                         String requirementName = requirements.getName();
3203                         resourceReqList.forEach(requirementDefinition -> {
3204                             if (requirementName.equals(requirementDefinition.getName()) && requirementDefinition.isExternal()) {
3205                                 requirements.setExternal(requirementDefinition.isExternal());
3206                             }
3207                         });
3208                     }
3209                 }
3210             });
3211         }
3212         if (MapUtils.isNotEmpty(component.getCapabilities())) {
3213             component.getCapabilities().entrySet().forEach(capabilityMap -> {
3214                 if (MapUtils.isNotEmpty(resResourceInfo.getCapabilities()) && resResourceInfo.getCapabilities().containsKey(capabilityMap.getKey())) {
3215                     List<CapabilityDefinition> resourceCapList = resResourceInfo.getCapabilities().get(capabilityMap.getKey());
3216                     capabilityMap.getValue().forEach(capabilities -> {
3217                         String capabilityName = capabilities.getName();
3218                         for (CapabilityDefinition capDef : resourceCapList) {
3219                             if (capabilityName.equals(capDef.getName()) && capDef.isExternal()) {
3220                                 capabilities.setExternal(capDef.isExternal());
3221                             }
3222                         }
3223                     });
3224                 }
3225             });
3226         }
3227     }
3228
3229     private boolean isFillProxyRes(StorageOperationStatus fillProxyRes) {
3230         if (fillProxyRes != StorageOperationStatus.OK) {
3231             log.debug("Failed to fill service proxy resource data with data from service, error {}", fillProxyRes);
3232             return true;
3233         }
3234         return false;
3235     }
3236
3237     // US831698
3238     public List<ComponentInstanceProperty> getComponentInstancePropertiesById(String containerComponentTypeParam, String containerComponentId,
3239                                                                               String componentInstanceUniqueId, String userId) {
3240         Component containerComponent = null;
3241
3242         boolean failed = false;
3243         try {
3244             validateUserExists(userId);
3245             validateComponentType(containerComponentTypeParam);
3246
3247             Either<Component, StorageOperationStatus> validateContainerComponentExists = toscaOperationFacade.getToscaElement(containerComponentId);
3248             if (validateContainerComponentExists.isRight()) {
3249                 throw new ByActionStatusComponentException(
3250                     componentsUtils.convertFromStorageResponse(validateContainerComponentExists.right().value()));
3251             }
3252             containerComponent = validateContainerComponentExists.left().value();
3253
3254             Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3255                 componentInstanceUniqueId);
3256             if (resourceInstanceStatus.isRight()) {
3257                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId,
3258                     containerComponentId);
3259             }
3260
3261             List<ComponentInstanceProperty> instanceProperties = new ArrayList<>();
3262             if (MapUtils.isNotEmpty(containerComponent.getComponentInstancesProperties())) {
3263                 instanceProperties = containerComponent.getComponentInstancesProperties()
3264                     .get(componentInstanceUniqueId);
3265             }
3266             return instanceProperties;
3267         } catch (ComponentException e) {
3268             failed = true;
3269             throw e;
3270         } finally {
3271             unlockComponent(failed, containerComponent);
3272         }
3273     }
3274
3275     public List<ComponentInstanceAttribute> getComponentInstanceAttributesById(final String containerComponentTypeParam,
3276                                                                                final String containerComponentId,
3277                                                                                final String componentInstanceUniqueId,
3278                                                                                final String userId) {
3279         Component containerComponent = null;
3280
3281         boolean failed = false;
3282         try {
3283             validateUserExists(userId);
3284             validateComponentType(containerComponentTypeParam);
3285
3286             final Either<Component, StorageOperationStatus> validateContainerComponentExists =
3287                 toscaOperationFacade.getToscaElement(containerComponentId);
3288             if (validateContainerComponentExists.isRight()) {
3289                 throw new ByActionStatusComponentException(
3290                     componentsUtils.convertFromStorageResponse(validateContainerComponentExists.right().value()));
3291             }
3292             containerComponent = validateContainerComponentExists.left().value();
3293
3294             if (getResourceInstanceById(containerComponent, componentInstanceUniqueId).isRight()) {
3295                 throw new ByActionStatusComponentException(
3296                     ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId);
3297             }
3298
3299             final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = containerComponent.getComponentInstancesAttributes();
3300             return componentInstancesAttributes == null ? new ArrayList<>()
3301                 : componentInstancesAttributes.getOrDefault(componentInstanceUniqueId, new ArrayList<>());
3302         } catch (final ComponentException e) {
3303             failed = true;
3304             throw e;
3305         } finally {
3306             unlockComponent(failed, containerComponent);
3307         }
3308     }
3309
3310     protected void validateIncrementCounter(String resourceInstanceId, GraphPropertiesDictionary counterType,
3311                                             Wrapper<Integer> instaceCounterWrapper,
3312                                             Wrapper<ResponseFormat> errorWrapper) {
3313         Either<Integer, StorageOperationStatus> counterRes = componentInstanceOperation
3314             .increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, counterType, true);
3315
3316         if (counterRes.isRight()) {
3317             log.debug("increase And Get {} failed resource instance {}", counterType, resourceInstanceId);
3318             StorageOperationStatus status = counterRes.right().value();
3319             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3320             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus));
3321         } else {
3322             instaceCounterWrapper.setInnerElement(counterRes.left().value());
3323         }
3324
3325     }
3326
3327     /**
3328      * updates componentInstance modificationTime
3329      *
3330      * @param componentInstance
3331      * @param componentInstanceType
3332      * @param modificationTime
3333      * @param inTransaction
3334      * @return
3335      */
3336     public Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceModificationTimeAndCustomizationUuid(
3337         ComponentInstance componentInstance, NodeTypeEnum componentInstanceType, Long modificationTime, boolean inTransaction) {
3338         Either<ComponentInstanceData, ResponseFormat> result;
3339         Either<ComponentInstanceData, StorageOperationStatus> updateComponentInstanceRes = componentInstanceOperation
3340             .updateComponentInstanceModificationTimeAndCustomizationUuidOnGraph(componentInstance, componentInstanceType, modificationTime,
3341                 inTransaction);
3342         if (updateComponentInstanceRes.isRight()) {
3343             log.debug("Failed to update component instance {} with new last update date and mofifier. Status is {}. ", componentInstance.getName(),
3344                 updateComponentInstanceRes.right().value());
3345             result = Either
3346                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateComponentInstanceRes.right().value())));
3347         } else {
3348             result = Either.left(updateComponentInstanceRes.left().value());
3349         }
3350         return result;
3351     }
3352
3353     public Either<ComponentInstance, ResponseFormat> deleteServiceProxy() {
3354         // TODO Add implementation
3355         return Either.left(new ComponentInstance());
3356     }
3357
3358     public Either<ComponentInstance, ResponseFormat> createServiceProxy() {
3359         // TODO Add implementation
3360         return Either.left(new ComponentInstance());
3361     }
3362
3363     public Either<ComponentInstance, ResponseFormat> changeServiceProxyVersion() {
3364         // TODO Add implementation
3365         return Either.left(new ComponentInstance());
3366     }
3367
3368     private Boolean validateInstanceNameUniquenessUponUpdate(Component containerComponent, ComponentInstance oldComponentInstance,
3369                                                              String newInstanceName) {
3370         return ComponentValidations.validateNameIsUniqueInComponent(oldComponentInstance.getName(), newInstanceName, containerComponent);
3371     }
3372
3373     private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(final Component containerComponent, final String instanceId) {
3374         final List<ComponentInstance> instances = containerComponent.getComponentInstances();
3375         if (CollectionUtils.isEmpty(instances)) {
3376             return Either.right(StorageOperationStatus.NOT_FOUND);
3377         }
3378
3379         final Optional<ComponentInstance> foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
3380         if (foundInstance.isEmpty()) {
3381             return Either.right(StorageOperationStatus.NOT_FOUND);
3382         }
3383
3384         return Either.left(foundInstance.get());
3385     }
3386
3387     private ComponentInstance buildComponentInstance(ComponentInstance resourceInstanceForUpdate, ComponentInstance origInstanceForUpdate) {
3388         Long creationDate = origInstanceForUpdate.getCreationTime();
3389         Long modificationTime = System.currentTimeMillis();
3390         resourceInstanceForUpdate.setCreationTime(creationDate);
3391         resourceInstanceForUpdate.setModificationTime(modificationTime);
3392         resourceInstanceForUpdate.setCustomizationUUID(origInstanceForUpdate.getCustomizationUUID());
3393         if (StringUtils.isEmpty(resourceInstanceForUpdate.getName()) && StringUtils.isNotEmpty(origInstanceForUpdate.getName())) {
3394             resourceInstanceForUpdate.setName(origInstanceForUpdate.getName());
3395         }
3396         resourceInstanceForUpdate.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(resourceInstanceForUpdate.getName()));
3397         if (StringUtils.isEmpty(resourceInstanceForUpdate.getIcon())) {
3398             resourceInstanceForUpdate.setIcon(origInstanceForUpdate.getIcon());
3399         }
3400         if (StringUtils.isEmpty(resourceInstanceForUpdate.getComponentVersion())) {
3401             resourceInstanceForUpdate.setComponentVersion(origInstanceForUpdate.getComponentVersion());
3402         }
3403         if (StringUtils.isEmpty(resourceInstanceForUpdate.getComponentName())) {
3404             resourceInstanceForUpdate.setComponentName(origInstanceForUpdate.getComponentName());
3405         }
3406         if (StringUtils.isEmpty(resourceInstanceForUpdate.getToscaComponentName())) {
3407             resourceInstanceForUpdate.setToscaComponentName(origInstanceForUpdate.getToscaComponentName());
3408         }
3409         if (resourceInstanceForUpdate.getOriginType() == null) {
3410             resourceInstanceForUpdate.setOriginType(origInstanceForUpdate.getOriginType());
3411         }
3412         if (resourceInstanceForUpdate.getOriginType() == OriginTypeEnum.ServiceProxy) {
3413             resourceInstanceForUpdate.setIsProxy(true);
3414         }
3415         if (resourceInstanceForUpdate.getSourceModelInvariant() == null) {
3416             resourceInstanceForUpdate.setSourceModelInvariant(origInstanceForUpdate.getSourceModelInvariant());
3417         }
3418         if (resourceInstanceForUpdate.getSourceModelName() == null) {
3419             resourceInstanceForUpdate.setSourceModelName(origInstanceForUpdate.getSourceModelName());
3420         }
3421         if (resourceInstanceForUpdate.getSourceModelUuid() == null) {
3422             resourceInstanceForUpdate.setSourceModelUuid(origInstanceForUpdate.getSourceModelUuid());
3423         }
3424         if (resourceInstanceForUpdate.getSourceModelUid() == null) {
3425             resourceInstanceForUpdate.setSourceModelUid(origInstanceForUpdate.getSourceModelUid());
3426         }
3427         if (resourceInstanceForUpdate.getCreatedFrom() == null) {
3428             resourceInstanceForUpdate.setCreatedFrom(origInstanceForUpdate.getCreatedFrom());
3429         }
3430         return resourceInstanceForUpdate;
3431     }
3432
3433     /**
3434      * Returns list of ComponentInstanceProperty belonging to component instance capability specified by name, type and ownerId
3435      *
3436      * @param containerComponentType
3437      * @param containerComponentId
3438      * @param componentInstanceUniqueId
3439      * @param capabilityType
3440      * @param capabilityName
3441      * @param userId
3442      * @param ownerId
3443      * @return
3444      */
3445     public List<ComponentInstanceProperty> getComponentInstanceCapabilityPropertiesById(String containerComponentType, String containerComponentId,
3446                                                                                         String componentInstanceUniqueId, String capabilityType,
3447                                                                                         String capabilityName, String ownerId, String userId) {
3448         Component containerComponent = null;
3449         List<ComponentInstanceProperty> resultOp = null;
3450         try {
3451             validateUserExists(userId);
3452             validateComponentType(containerComponentType);
3453             containerComponent = toscaOperationFacade.getToscaFullElement(containerComponentId).left().on(this::componentException);
3454             ComponentInstance resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId).left()
3455                 .on(this::componentInstanceException);
3456             resultOp = findCapabilityOfInstance(containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, ownerId,
3457                 resourceInstanceStatus.getCapabilities());
3458         } catch (StorageException | ComponentException e) {
3459             unlockRollbackWithException(containerComponent, e);
3460         } catch (Exception e) {
3461             unlockRollbackWithException(containerComponent, new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR));
3462         }
3463         unlockWithCommit(containerComponent);
3464         return resultOp;
3465     }
3466
3467     private List<ComponentInstanceProperty> findCapabilityOfInstance(String componentId, String instanceId, String capabilityType,
3468                                                                      String capabilityName, String ownerId,
3469                                                                      Map<String, List<CapabilityDefinition>> instanceCapabilities) {
3470         CapabilityDefinition foundCapability;
3471         if (MapUtils.isNotEmpty(instanceCapabilities)) {
3472             List<CapabilityDefinition> capabilitiesPerType = instanceCapabilities.get(capabilityType);
3473             if (capabilitiesPerType != null) {
3474                 Optional<CapabilityDefinition> capabilityOpt = capabilitiesPerType.stream()
3475                     .filter(c -> c.getName().equals(capabilityName) && c.getOwnerId().equals(ownerId)).findFirst();
3476                 if (capabilityOpt.isPresent()) {
3477                     foundCapability = capabilityOpt.get();
3478                     return foundCapability.getProperties() == null ? new ArrayList<>() : foundCapability.getProperties();
3479                 }
3480             }
3481         }
3482         return fetchComponentInstanceCapabilityProperties(componentId, instanceId, capabilityType, capabilityName, ownerId);
3483     }
3484
3485     private List<ComponentInstanceProperty> fetchComponentInstanceCapabilityProperties(String componentId, String instanceId, String capabilityType,
3486                                                                                        String capabilityName, String ownerId) {
3487         try {
3488             return toscaOperationFacade.getComponentInstanceCapabilityProperties(componentId, instanceId, capabilityName, capabilityType, ownerId)
3489                 .left().on(this::componentInstancePropertyListException);
3490         } catch (Exception e) {
3491             log.debug("The exception {} occurred upon the component {} instance {} capability {} properties retrieving. ", componentId, instanceId,
3492                 capabilityName, e);
3493             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3494         }
3495     }
3496
3497     public Either<RequirementDefinition, ResponseFormat> updateInstanceRequirement(ComponentTypeEnum componentTypeEnum, String containerComponentId,
3498                                                                                    String componentInstanceUniqueId,
3499                                                                                    RequirementDefinition requirementDef, String userId) {
3500         Either<RequirementDefinition, ResponseFormat> resultOp = null;
3501         validateUserExists(userId);
3502         if (componentTypeEnum == null) {
3503             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceRequirement", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3504             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3505         }
3506         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3507         if (getResourceResult.isRight()) {
3508             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3509             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3510         }
3511         Component containerComponent = getResourceResult.left().value();
3512         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3513             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3514             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3515         }
3516         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3517             componentInstanceUniqueId);
3518         if (resourceInstanceStatus.isRight()) {
3519             return Either.right(componentsUtils
3520                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3521         }
3522         // lock resource
3523         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
3524         if (lockStatus != StorageOperationStatus.OK) {
3525             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3526             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3527         }
3528         try {
3529             StorageOperationStatus updateRequirementStatus = toscaOperationFacade
3530                 .updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDef);
3531             if (updateRequirementStatus != StorageOperationStatus.OK) {
3532                 log.debug("Failed to update component instance requirement on instance {} in container {}", componentInstanceUniqueId,
3533                     containerComponentId);
3534                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateRequirementStatus)));
3535             }
3536             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3537                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3538             if (updateContainerRes.isRight()) {
3539                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3540                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3541                 return resultOp;
3542             }
3543             resultOp = Either.left(requirementDef);
3544             return resultOp;
3545         } finally {
3546             if (resultOp == null || resultOp.isRight()) {
3547                 janusGraphDao.rollback();
3548             } else {
3549                 janusGraphDao.commit();
3550             }
3551             // unlock resource
3552             graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType());
3553         }
3554     }
3555
3556     public Either<CapabilityDefinition, ResponseFormat> updateInstanceCapability(final ComponentTypeEnum containerComponentType,
3557                                                                                  final String containerComponentId,
3558                                                                                  final String componentInstanceUniqueId,
3559                                                                                  final CapabilityDefinition capabilityDefinition,
3560                                                                                  final String userId) {
3561         if (containerComponentType == null) {
3562             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceCapability", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3563             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3564         }
3565         validateUserExists(userId);
3566         final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3567         if (getResourceResult.isRight()) {
3568             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3569             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_FOUND, containerComponentId));
3570         }
3571         final Component containerComponent = getResourceResult.left().value();
3572         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3573             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3574             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3575         }
3576         final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus =
3577             getResourceInstanceById(containerComponent, componentInstanceUniqueId);
3578         if (resourceInstanceStatus.isRight()) {
3579             return Either.right(componentsUtils
3580                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3581         }
3582         // lock resource
3583         final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, containerComponentType.getNodeType());
3584         if (lockStatus != StorageOperationStatus.OK) {
3585             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3586             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3587         }
3588         var success = false;
3589         try {
3590             final CapabilityDataDefinition updatedCapabilityDefinition = toscaOperationFacade
3591                 .updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition);
3592             final Either<Component, StorageOperationStatus> updateContainerEither = toscaOperationFacade
3593                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3594             if (updateContainerEither.isRight()) {
3595                 var actionStatus = componentsUtils.convertFromStorageResponse(updateContainerEither.right().value(), containerComponentType);
3596                 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3597             }
3598             success = true;
3599             return Either.left(new CapabilityDefinition(updatedCapabilityDefinition));
3600         } catch (final BusinessException e) {
3601             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
3602                 FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
3603             throw e;
3604         } catch (final Exception e) {
3605             log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
3606                 FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
3607             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
3608         } finally {
3609             if (success) {
3610                 janusGraphDao.commit();
3611             } else {
3612                 janusGraphDao.rollback();
3613             }
3614             // unlock resource
3615             graphLockOperation.unlockComponent(containerComponentId, containerComponentType.getNodeType());
3616         }
3617     }
3618
3619     public Either<List<ComponentInstanceProperty>, ResponseFormat> updateInstanceCapabilityProperties(ComponentTypeEnum componentTypeEnum,
3620                                                                                                       String containerComponentId,
3621                                                                                                       String componentInstanceUniqueId,
3622                                                                                                       String capabilityType, String capabilityName,
3623                                                                                                       List<ComponentInstanceProperty> properties,
3624                                                                                                       String userId) {
3625         Either<List<ComponentInstanceProperty>, ResponseFormat> resultOp = null;
3626         validateUserExists(userId);
3627         if (componentTypeEnum == null) {
3628             BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceCapabilityProperty", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3629             return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3630         }
3631         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
3632         if (getResourceResult.isRight()) {
3633             log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
3634             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3635         }
3636         Component containerComponent = getResourceResult.left().value();
3637         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
3638             log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
3639             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3640         }
3641         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
3642             componentInstanceUniqueId);
3643         if (resourceInstanceStatus.isRight()) {
3644             return Either.right(componentsUtils
3645                 .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
3646         }
3647         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
3648         // lock resource
3649         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
3650         if (lockStatus != StorageOperationStatus.OK) {
3651             log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
3652             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
3653         }
3654         try {
3655             for (ComponentInstanceProperty property : properties) {
3656                 Either<String, ResponseFormat> newPropertyValueEither = validatePropertyObjectValue(property, property.getValue(), false);
3657                 newPropertyValueEither.bimap(
3658                     updatedValue -> updateCapabilityPropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance,
3659                         capabilityType, capabilityName), Either::right);
3660             }
3661             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3662                 .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3663             if (updateContainerRes.isRight()) {
3664                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3665                 resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3666                 return resultOp;
3667             }
3668             resultOp = Either.left(properties);
3669             return resultOp;
3670         } finally {
3671             if (resultOp == null || resultOp.isRight()) {
3672                 janusGraphDao.rollback();
3673             } else {
3674                 janusGraphDao.commit();
3675             }
3676             // unlock resource
3677             graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType());
3678         }
3679     }
3680
3681     public Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance(ComponentInstance inputComponentInstance,
3682                                                                                         String containerComponentId, String componentInstanceId,
3683                                                                                         String userId) {
3684         Map<String, ComponentInstance> resultMap = new HashMap<>();
3685         Either<Component, StorageOperationStatus> getOrigComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3686         if (getOrigComponent.isRight()) {
3687             log.error("Failed to get the original component information");
3688             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3689         }
3690         Component origComponent = getOrigComponent.left().value();
3691         try {
3692             lockComponent(origComponent, "copyComponentInstance");
3693         } catch (ComponentException e) {
3694             log.error("destComponentInstance's data is {}", origComponent.toString());
3695             return Either.right(componentsUtils
3696                 .getResponseFormat(ActionStatus.USER_DEFINED, "Failed to lock component destComponentInstance's data is {}",
3697                     origComponent.toString()));
3698         }
3699         boolean failed = false;
3700         ComponentInstance actionResponse = null;
3701         try {
3702             actionResponse = createComponentInstance("services", containerComponentId, userId, inputComponentInstance, false);
3703         } catch (ComponentException e) {
3704             failed = true;
3705             // on failure of the create instance unlock the resource and rollback the transaction.
3706             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3707         } finally {
3708             // on failure of the create instance unlock the resource and rollback the transaction.
3709             if (null == actionResponse) {
3710                 log.error(FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS);
3711                 unlockComponent(failed, origComponent);
3712             }
3713         }
3714         Either<String, ResponseFormat> resultOp = null;
3715         try {
3716             ComponentInstance destComponentInstance = actionResponse;
3717             log.debug("destComponentInstance's data is {}", destComponentInstance);
3718             resultOp = deepCopyComponentInstance(origComponent, containerComponentId, componentInstanceId, destComponentInstance, userId);
3719             resultMap.put("componentInstance", destComponentInstance);
3720         } finally {
3721             // unlock resource
3722             if (resultOp == null || resultOp.isRight()) {
3723                 unlockComponent(true, origComponent);
3724                 janusGraphDao.rollback();
3725                 log.error("Failed to deep copy component instance");
3726             } else {
3727                 unlockComponent(false, origComponent);
3728                 janusGraphDao.commit();
3729                 log.debug("Success trasaction commit");
3730             }
3731         }
3732         if (resultOp == null || resultOp.isRight()) {
3733             return Either
3734                 .right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, "Failed to deep copy the component instance to the canvas"));
3735         } else {
3736             return Either.left(resultMap);
3737         }
3738     }
3739
3740     private Either<String, ResponseFormat> deepCopyComponentInstance(Component sourceComponent, String containerComponentId,
3741                                                                      String sourceComponentInstanceId, ComponentInstance destComponentInstance,
3742                                                                      String userId) {
3743         Either<Component, StorageOperationStatus> getDestComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3744         if (getDestComponent.isRight()) {
3745             log.error("Failed to get the dest component information");
3746             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS));
3747         }
3748         Component destComponent = getDestComponent.left().value();
3749         Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs = copyComponentInstanceWithPropertiesAndInputs(sourceComponent,
3750             destComponent, sourceComponentInstanceId, destComponentInstance);
3751         if (copyComponentInstanceWithPropertiesAndInputs.isRight()) {
3752             log.error("Failed to copy component instance with properties and inputs as part of deep copy");
3753             return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED,
3754                 "Failed to copy the component instance with properties and inputs as part of deep copy"));
3755         }
3756         Either<String, ResponseFormat> copyComponentInstanceWithAttributes = copyComponentInstanceWithAttributes(sourceComponent, destComponent,
3757             sourceComponentInstanceId, destComponentInstance, userId);
3758         if (copyComponentInstanceWithAttributes.isRight()) {
3759             log.error("Failed to copy component instance with attributes as part of deep copy");
3760             return Either.right(componentsUtils
3761                 .getResponseFormat(ActionStatus.USER_DEFINED, "Failed to copy the component instance with attributes as part of deep copy"));
3762         }
3763         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3764     }
3765
3766     private Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs(Component sourceComponent, Component destComponent,
3767                                                                                         String sourceComponentInstanceId,
3768                                                                                         ComponentInstance destComponentInstance) {
3769         log.debug("start to copy ComponentInstance with properties and inputs");
3770         List<ComponentInstanceProperty> sourcePropList = null;
3771         if (sourceComponent.getComponentInstancesProperties() != null
3772             && sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId) != null) {
3773             sourcePropList = sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId);
3774             log.debug("sourcePropList");
3775         }
3776         List<ComponentInstanceProperty> destPropList = null;
3777         String destComponentInstanceId = destComponentInstance.getUniqueId();
3778         log.debug("destComponentInstanceId: {}", destComponentInstance.getUniqueId());
3779         if (destComponent.getComponentInstancesProperties() != null
3780             && destComponent.getComponentInstancesProperties().get(destComponentInstanceId) != null) {
3781             destPropList = destComponent.getComponentInstancesProperties().get(destComponentInstanceId);
3782             log.debug("destPropList {}");
3783         }
3784         List<ComponentInstancePropInput> componentInstancePropInputList = new ArrayList<>();
3785         if (null != destPropList && null != sourcePropList) {
3786             log.debug("start to set property and attribute");
3787             for (ComponentInstanceProperty destProp : destPropList) {
3788                 String destPropertyName = destProp.getName();
3789                 for (ComponentInstanceProperty sourceProp : sourcePropList) {
3790                     if (!destPropertyName.equals(sourceProp.getName())) {
3791                         continue;
3792                     }
3793                     log.debug("now set property");
3794                     final List<GetInputValueDataDefinition> getInputValues = sourceProp.getGetInputValues();
3795                     if (getInputValues == null && !StringUtils.isEmpty(sourceProp.getValue()) && (destProp.getValue() == null || !destProp.getValue()
3796                         .equals(sourceProp.getValue()))) {
3797                         log.debug("Now starting to copy the property {} in value {}", destPropertyName, sourceProp.getValue());
3798                         destProp.setValue(sourceProp.getValue());
3799                         Either<String, ResponseFormat> updatePropertyValueEither = updateComponentInstanceProperty(destComponent.getUniqueId(),
3800                             destComponentInstanceId, destProp);
3801                         if (updatePropertyValueEither.isRight()) {
3802                             log.error("Failed to copy the property {}", destPropertyName);
3803                             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
3804                                 "Failed to paste component instance to the canvas, property copy"));
3805                         }
3806                         break;
3807                     }
3808                     log.debug("Now start to update inputs");
3809                     if (getInputValues != null) {
3810                         if (getInputValues.isEmpty()) {
3811                             log.debug("property is return from input, set by man");
3812                             break;
3813                         }
3814                         log.debug("Now starting to copy the {} property", destPropertyName);
3815                         Either<String, ResponseFormat> getSourceInputDefaultValue = getInputListDefaultValue(sourceComponent,
3816                             getInputValues.get(0).getInputId());
3817                         if (getSourceInputDefaultValue.isRight()) {
3818                             return Either.right(getSourceInputDefaultValue.right().value());
3819                         }
3820                         componentInstancePropInputList.add(new ComponentInstancePropInput(destProp));
3821                     }
3822                 }
3823             }
3824         }
3825         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3826     }
3827
3828     private Either<String, ResponseFormat> copyComponentInstanceWithAttributes(Component sourceComponent, Component destComponent,
3829                                                                                String sourceComponentInstanceId,
3830                                                                                ComponentInstance destComponentInstance, String userId) {
3831         String destComponentInstanceId = destComponentInstance.getUniqueId();
3832         log.info("start to copy component instance with attributes");
3833         List<ComponentInstanceAttribute> sourceAttributeList = null;
3834         if (sourceComponent.getComponentInstancesAttributes() != null
3835             && sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId) != null) {
3836             sourceAttributeList = sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId);
3837             log.info("sourceAttributes {}");
3838         }
3839         List<ComponentInstanceAttribute> destAttributeList = null;
3840         if (destComponent.getComponentInstancesAttributes() != null
3841             && destComponent.getComponentInstancesAttributes().get(destComponentInstanceId) != null) {
3842             destAttributeList = destComponent.getComponentInstancesAttributes().get(destComponentInstanceId);
3843             log.info("destAttributeList {}");
3844         }
3845         if (null != sourceAttributeList && null != destAttributeList) {
3846             log.info("set attribute");
3847             for (ComponentInstanceAttribute sourceAttribute : sourceAttributeList) {
3848                 String sourceAttributeName = sourceAttribute.getName();
3849                 for (ComponentInstanceAttribute destAttribute : destAttributeList) {
3850                     if (sourceAttributeName.equals(destAttribute.getName())) {
3851                         log.debug("Start to copy the attribute exists {}", sourceAttributeName);
3852                         sourceAttribute.setUniqueId(
3853                             UniqueIdBuilder.buildResourceInstanceUniqueId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName));
3854                         Either<ComponentInstanceAttribute, ResponseFormat> updateAttributeValueEither = createOrUpdateAttributeValueForCopyPaste(
3855                             ComponentTypeEnum.SERVICE, destComponent.getUniqueId(), destComponentInstanceId, sourceAttribute, userId);
3856                         if (updateAttributeValueEither.isRight()) {
3857                             log.error("Failed to copy the attribute");
3858                             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
3859                                 "Failed to paste component instance to the canvas, attribute copy"));
3860                         }
3861                         break;
3862                     }
3863                 }
3864             }
3865         }
3866         return Either.left(COPY_COMPONENT_INSTANCE_OK);
3867     }
3868
3869     private Either<ComponentInstanceAttribute, ResponseFormat> createOrUpdateAttributeValueForCopyPaste(ComponentTypeEnum componentTypeEnum,
3870                                                                                                         String componentId, String resourceInstanceId,
3871                                                                                                         ComponentInstanceAttribute attribute,
3872                                                                                                         String userId) {
3873         Either<ComponentInstanceAttribute, ResponseFormat> resultOp = null;
3874         validateUserExists(userId);
3875         if (componentTypeEnum == null) {
3876             BeEcompErrorManager.getInstance()
3877                 .logInvalidInputError("createOrUpdateAttributeValueForCopyPaste", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
3878             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
3879             return resultOp;
3880         }
3881         Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
3882         if (getResourceResult.isRight()) {
3883             log.info("Failed to retrieve component id {}", componentId);
3884             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
3885             return resultOp;
3886         }
3887         Component containerComponent = getResourceResult.left().value();
3888         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
3889         if (resourceInstanceStatus.isRight()) {
3890             resultOp = Either
3891                 .right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, resourceInstanceId, componentId));
3892             return resultOp;
3893         }
3894         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
3895         String propertyType = attribute.getType();
3896         ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
3897         log.info("The type of attribute id{},is {} ", attribute.getUniqueId(), propertyType);
3898         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
3899             SchemaDefinition def = attribute.getSchema();
3900             if (def == null) {
3901                 log.info("Schema doesn't exists for attribute of type {}", type);
3902                 return Either
3903                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
3904             }
3905             PropertyDataDefinition propDef = def.getProperty();
3906             if (propDef == null) {
3907                 log.info("Attribute in Schema Definition inside attribute of type {} doesn't exist", type);
3908                 return Either
3909                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
3910             }
3911         }
3912         List<ComponentInstanceAttribute> instanceAttributes = containerComponent.getComponentInstancesAttributes().get(resourceInstanceId);
3913         Optional<ComponentInstanceAttribute> instanceAttribute = instanceAttributes.stream()
3914             .filter(p -> p.getUniqueId().equals(attribute.getUniqueId())).findAny();
3915         StorageOperationStatus status;
3916         if (instanceAttribute.isPresent()) {
3917             log.info("updateComponentInstanceAttribute");
3918             status = toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute);
3919         } else {
3920             log.info("addComponentInstanceAttribute");
3921             status = toscaOperationFacade.addComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute);
3922         }
3923         if (status != StorageOperationStatus.OK) {
3924             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3925             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3926             return resultOp;
3927         }
3928         List<String> path = new ArrayList<>();
3929         path.add(foundResourceInstance.getUniqueId());
3930         attribute.setPath(path);
3931         foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
3932         Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3933             .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3934         if (updateContainerRes.isRight()) {
3935             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3936             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3937             return resultOp;
3938         }
3939         resultOp = Either.left(attribute);
3940         return resultOp;
3941     }
3942
3943     private Either<String, ResponseFormat> updateComponentInstanceProperty(String containerComponentId, String componentInstanceId,
3944                                                                            ComponentInstanceProperty property) {
3945         Either<String, ResponseFormat> resultOp;
3946         Either<Component, StorageOperationStatus> getComponent = toscaOperationFacade.getToscaElement(containerComponentId);
3947         if (getComponent.isRight()) {
3948             log.error("Failed to get the component information");
3949             return Either.right(componentsUtils
3950                 .getResponseFormatForResourceInstanceProperty(ActionStatus.INVALID_CONTENT_PARAM, "Failed to get the component information"));
3951         }
3952         Component containerComponent = getComponent.left().value();
3953         StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
3954         if (status != StorageOperationStatus.OK) {
3955             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
3956             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3957             return resultOp;
3958         }
3959         Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
3960             .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
3961         if (updateContainerRes.isRight()) {
3962             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
3963             resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
3964             return resultOp;
3965         }
3966         return Either.left("Update OK");
3967     }
3968
3969     private Either<String, ResponseFormat> getInputListDefaultValue(Component component, String inputId) {
3970         List<InputDefinition> inputList = component.getInputs();
3971         for (InputDefinition input : inputList) {
3972             if (input.getUniqueId().equals(inputId)) {
3973                 if (input.getDefaultValue() == null) {
3974                     log.debug("The input's default value is null");
3975                     return Either.left(null);
3976                 }
3977                 return Either.left(input.getDefaultValue());
3978             }
3979         }
3980         log.error("The input's default value with id {} is not found", inputId);
3981         return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, "Failed to paste component instance to the canvas"));
3982     }
3983
3984     /**
3985      * Method to delete selected nodes and edges on composition page
3986      *
3987      * @param containerComponentType
3988      * @param componentId
3989      * @param componentInstanceIdList
3990      * @param userId
3991      * @return
3992      */
3993     public Map<String, List<String>> batchDeleteComponentInstance(String containerComponentType, String componentId,
3994                                                                   List<String> componentInstanceIdList, String userId) {
3995         List<String> deleteErrorIds = new ArrayList<>();
3996         Map<String, List<String>> deleteErrorMap = new HashMap<>();
3997         validateUserExists(userId);
3998         org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId,
3999             ComponentTypeEnum.findByParamName(containerComponentType), null);
4000         boolean failed = false;
4001         try {
4002             lockComponent(containerComponent, "batchDeleteComponentInstance");
4003             for (String eachInstanceId : componentInstanceIdList) {
4004                 Either<ComponentInstance, ResponseFormat> actionResponse = batchDeleteComponentInstance(containerComponent, containerComponentType,
4005                     eachInstanceId);
4006                 log.debug("batchDeleteResourceInstances actionResponse is {}", actionResponse);
4007                 if (actionResponse.isRight()) {
4008                     log.error("Failed to delete ComponentInstance [{}]", eachInstanceId);
4009                     deleteErrorIds.add(eachInstanceId);
4010                 }
4011             }
4012             //sending the ids of the error nodes that were not deleted to UI
4013             deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
4014             return deleteErrorMap;
4015         } catch (ComponentException e) {
4016             failed = true;
4017             throw e;
4018         } finally {
4019             unlockComponent(failed, containerComponent);
4020         }
4021     }
4022
4023     private Either<ComponentInstance, ResponseFormat> batchDeleteComponentInstance(Component containerComponent, String containerComponentType,
4024                                                                                    String componentInstanceId) {
4025         ComponentInstance resultOp;
4026         final ComponentTypeEnum containerComponentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
4027         try {
4028             resultOp = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentTypeEnum);
4029             log.info("Successfully deleted instance with id {}", componentInstanceId);
4030             return Either.left(resultOp);
4031         } catch (ComponentException e) {
4032             log.error("Failed to deleteComponentInstance with instanceId[{}]", componentInstanceId);
4033             return Either.right(new ResponseFormat());
4034         }
4035     }
4036
4037     private void validatePropertyConstraintsNotChanged(List<ComponentInstanceProperty> newProperties, ComponentInstance originalResourceInstance) {
4038         for (ComponentInstanceProperty newProperty : newProperties) {
4039             Optional<PropertyDefinition> originalProperty = originalResourceInstance.getProperties().stream()
4040                 .filter(prop -> prop.getUniqueId().equals(newProperty.getUniqueId())).findAny();
4041             if (originalProperty.isPresent()) {
4042                 List<PropertyConstraint> originalConstraints = originalProperty.get().getConstraints();
4043                 List<PropertyConstraint> newConstraints = newProperty.getConstraints();
4044                 if (!Objects.equals(originalConstraints, newConstraints)) {
4045                     throw new ByActionStatusComponentException(ActionStatus.CANNOT_CHANGE_CONSTRAINTS);
4046                 }
4047             } else {
4048                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getUniqueId());
4049             }
4050         }
4051     }
4052
4053     private Either<Boolean, ResponseFormat> validatePropertyValueConstraint(List<? extends PropertyDefinition> properties, final String componentId) {
4054         try {
4055             String propertyModel = propertyBusinessLogic.getComponentModelByComponentId(componentId);
4056             PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil();
4057             return propertyValueConstraintValidationUtil.validatePropertyConstraints(properties, applicationDataTypeCache, propertyModel);
4058         } catch (BusinessLogicException e) {
4059             return Either.right(e.getResponseFormat());
4060         }
4061     }
4062
4063     public void validateUser(final String userId) {
4064         final User user = userValidations.validateUserExists(userId);
4065         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
4066     }
4067
4068     public void setCompositionBusinessLogic(CompositionBusinessLogic compositionBusinessLogic) {
4069         this.compositionBusinessLogic = compositionBusinessLogic;
4070     }
4071
4072     public void setContainerInstanceTypesData(ContainerInstanceTypesData containerInstanceTypesData) {
4073         this.containerInstanceTypesData = containerInstanceTypesData;
4074     }
4075
4076 }