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