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