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