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