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