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