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