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