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