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