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