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