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