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