f8aab3def16c8956835d33ac5d871198e1728e5d
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / PolicyBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2021 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.openecomp.sdc.be.components.impl;
22
23 import static java.util.stream.Collectors.toMap;
24 import static org.openecomp.sdc.be.components.validation.PolicyUtils.getExcludedPolicyTypesByComponent;
25 import static org.openecomp.sdc.be.components.validation.PolicyUtils.getNextPolicyCounter;
26 import static org.openecomp.sdc.be.components.validation.PolicyUtils.validatePolicyFields;
27
28 import fj.data.Either;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.EnumMap;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Optional;
37 import java.util.Set;
38 import java.util.function.Function;
39 import java.util.stream.Collectors;
40 import org.apache.commons.collections.CollectionUtils;
41 import org.apache.commons.collections.MapUtils;
42 import org.apache.commons.lang3.StringUtils;
43 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
44 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
45 import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
46 import org.openecomp.sdc.be.components.validation.PolicyUtils;
47 import org.openecomp.sdc.be.dao.api.ActionStatus;
48 import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
50 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
51 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
52 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
53 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
54 import org.openecomp.sdc.be.model.Component;
55 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
56 import org.openecomp.sdc.be.model.ComponentInstance;
57 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
58 import org.openecomp.sdc.be.model.ComponentParametersView;
59 import org.openecomp.sdc.be.model.PolicyDefinition;
60 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
61 import org.openecomp.sdc.be.model.Resource;
62 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
63 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
64 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
65 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
66 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
67 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
68 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
69 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
70 import org.openecomp.sdc.common.datastructure.Wrapper;
71 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
72 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
73 import org.openecomp.sdc.common.log.enums.StatusCode;
74 import org.openecomp.sdc.common.log.wrappers.Logger;
75 import org.openecomp.sdc.exception.ResponseFormat;
76 import org.springframework.beans.factory.annotation.Autowired;
77
78 /**
79  * Provides specified business logic to create, retrieve, update, delete a policy
80  */
81 @org.springframework.stereotype.Component("policyBusinessLogic")
82 public class PolicyBusinessLogic extends BaseBusinessLogic {
83
84     private static final String DECLARE_PROPERTIES_TO_POLICIES = "declare properties to policies";
85     private static final Logger log = Logger.getLogger(PolicyBusinessLogic.class);
86     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(PolicyBusinessLogic.class.getName());
87     private PropertyDeclarationOrchestrator propertyDeclarationOrchestrator;
88
89     @Autowired
90     public PolicyBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
91                                IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
92                                InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
93         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
94             artifactToscaOperation);
95     }
96
97     @Autowired
98     public void setPropertyDeclarationOrchestrator(PropertyDeclarationOrchestrator propertyDeclarationOrchestrator) {
99         this.propertyDeclarationOrchestrator = propertyDeclarationOrchestrator;
100     }
101
102     /**
103      * Adds the newly created policy of the specified type to the component
104      *
105      * @param componentType  the type of the component
106      * @param componentId    the id of the component which the policy resides under
107      * @param policyTypeName the name of the policy type
108      * @param userId         the user creator id
109      * @param shouldLock     the flag defining if the component should be locked
110      * @return a policy or an error in a response format
111      */
112     public PolicyDefinition createPolicy(ComponentTypeEnum componentType, String componentId, String policyTypeName, String userId,
113                                          boolean shouldLock) {
114         log.trace("#createPolicy - starting to create policy of the type {} on the component {}. ", policyTypeName, componentId);
115         Component component = null;
116         boolean failed = false;
117         try {
118             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
119             return createPolicy(policyTypeName, component);
120         } catch (ComponentException e) {
121             failed = true;
122             throw e;
123         } finally {
124             unlockComponent(shouldLock, failed, component);
125         }
126     }
127
128     public Map<String, PolicyDefinition> createPoliciesFromParsedCsar(Component component,
129                                                                       final Map<String, PolicyDefinition> incomingPolicyDefinitions) {
130         if (MapUtils.isEmpty(incomingPolicyDefinitions)) {
131             return Collections.emptyMap();
132         }
133         Map<String, PolicyDefinition> createdPolicies = new HashMap<>();
134         for (Map.Entry<String, PolicyDefinition> policyEntry : incomingPolicyDefinitions.entrySet()) {
135             PolicyDefinition incomingPolicyDefinition = policyEntry.getValue();
136             String policyName = incomingPolicyDefinition.getName();
137             log.trace("Going to create policy {}", incomingPolicyDefinition);
138             loggerSupportability
139                 .log(LoggerSupportabilityActions.CREATE_GROUP_POLICY, component.getComponentMetadataForSupportLog(), StatusCode.STARTED,
140                     "Start to create policy: {} for component {}", policyName, component.getName());
141             String policyType = incomingPolicyDefinition.getType();
142             if (StringUtils.isEmpty(policyType)) {
143                 log.debug("Policy type '{}' for policy '{}' not found.", policyType, policyName);
144                 throw new ByActionStatusComponentException(ActionStatus.POLICY_MISSING_POLICY_TYPE, policyName);
145             }
146             // create policyDefinition
147             String policyTypeName = incomingPolicyDefinition.getPolicyTypeName();
148             PolicyDefinition createdPolicyDefinition = createPolicy(policyTypeName, component);
149             // set isFromCsar
150             createdPolicyDefinition.setToscaPresentationValue(JsonPresentationFields.IS_FROM_CSAR, true);
151             // link policy to component
152             component.addPolicy(createdPolicyDefinition);
153             // process targets
154             Map<PolicyTargetType, List<String>> policyTargets = incomingPolicyDefinition.getTargets();
155             createdPolicyDefinition = setUpdatePolicyTargets(component, createdPolicyDefinition, policyTargets);
156             // process policy properties
157             List<PropertyDataDefinition> properties = incomingPolicyDefinition.getProperties();
158             createdPolicyDefinition = setUpdatePolicyProperties(component, createdPolicyDefinition, properties);
159             createdPolicies.put(policyName, createdPolicyDefinition);
160             loggerSupportability.log(LoggerSupportabilityActions.CREATE_POLICIES, component.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
161                 "policy {} has been created ", policyName);
162         }
163         return createdPolicies;
164     }
165
166     private PolicyDefinition setUpdatePolicyProperties(Component component, PolicyDefinition policyDefinition,
167                                                        List<PropertyDataDefinition> properties) {
168         if (CollectionUtils.isNotEmpty(properties)) {
169             PropertyDataDefinition[] propertiesArray = properties.toArray(new PropertyDataDefinition[properties.size()]);
170             List<PropertyDataDefinition> updatedPropertiesList = setComponentValidateUpdatePolicyProperties(policyDefinition.getUniqueId(),
171                 propertiesArray, component);
172             policyDefinition.setProperties(updatedPropertiesList);
173         }
174         return policyDefinition;
175     }
176
177     private PolicyDefinition setUpdatePolicyTargets(Component component, PolicyDefinition policyDefinition,
178                                                     Map<PolicyTargetType, List<String>> targets) {
179         if (MapUtils.isEmpty(targets)) {
180             return policyDefinition;
181         }
182         List<String> targetsToUpdate = targets.get(PolicyTargetType.COMPONENT_INSTANCES);
183         if (CollectionUtils.isEmpty(targetsToUpdate)) {
184             return policyDefinition;
185         }
186         // update targets to uniqueIds of respective component instance
187         List<String> targetsUniqueIds = new ArrayList<>();
188         for (String targetName : targetsToUpdate) {
189             Optional<ComponentInstance> componentInstance = component.getComponentInstanceByName(targetName);
190             String componentUniqueId = componentInstance
191                 .orElseThrow(() -> new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND)).getUniqueId();
192             targetsUniqueIds.add(componentUniqueId);
193         }
194         EnumMap<PolicyTargetType, List<String>> updatedTargets = new EnumMap<>(PolicyTargetType.class);
195         updatedTargets.put(PolicyTargetType.COMPONENT_INSTANCES, targetsUniqueIds);
196         policyDefinition.setTargets(updatedTargets);
197         policyDefinition = validateAndUpdatePolicyTargets(component, policyDefinition.getUniqueId(), policyDefinition.getTargets());
198         return policyDefinition;
199     }
200
201     public Either<List<PolicyDefinition>, ResponseFormat> getPoliciesList(ComponentTypeEnum componentType, String componentId, String userId) {
202         Either<List<PolicyDefinition>, ResponseFormat> result;
203         log.trace("#getPolicies - starting to retrieve policies of component {}. ", componentId);
204         try {
205             Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
206             result = Either.left(component.resolvePoliciesList());
207         } catch (Exception e) {
208             log.error("#getPolicy - the exception occurred upon retrieving policies list of component {}: ", componentId, e);
209             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
210         }
211         return result;
212     }
213
214     /**
215      * Retrieves the policy of the component by UniqueId
216      *
217      * @param componentType the type of the component
218      * @param componentId   the ID of the component
219      * @param policyId      the ID of the policy
220      * @param userId        the ID of the user
221      * @return either policy or error response
222      */
223     public PolicyDefinition getPolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
224         log.trace("#getPolicy - starting to retrieve the policy {} of the component {}. ", policyId, componentId);
225         Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
226         return getPolicyById(component, policyId);
227     }
228
229     /**
230      * Updates the policy of the component
231      *
232      * @param componentType the type of the component
233      * @param componentId   the id of the component which the policy resides under
234      * @param policy        the policy to update
235      * @param userId        the user modifier id
236      * @param shouldLock    the flag defining if the component should be locked
237      * @return a policy or an error in a response format
238      */
239     public PolicyDefinition updatePolicy(ComponentTypeEnum componentType, String componentId, PolicyDefinition policy, String userId,
240                                          boolean shouldLock) {
241         Component component = null;
242         boolean failed = false;
243         log.trace("#updatePolicy - starting to update the policy {} on the component {}. ", policy.getUniqueId(), componentId);
244         try {
245             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
246             return validateAndUpdatePolicy(component, policy);
247         } catch (ComponentException e) {
248             failed = true;
249             log.error("#updatePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policy.getUniqueId(),
250                 componentId, e);
251             throw e;
252         } finally {
253             //TODO Andrey result = boolean
254             unlockComponent(shouldLock, failed, component);
255         }
256     }
257
258     /**
259      * Deletes the policy from the component
260      *
261      * @param componentType the type of the component
262      * @param componentId   the id of the component which the policy resides under
263      * @param policyId      the id of the policy which its properties to return
264      * @param userId        the user modifier id
265      * @param shouldLock    the flag defining if the component should be locked
266      * @return a policy or an error in a response format
267      */
268     public PolicyDefinition deletePolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId, boolean shouldLock) {
269         PolicyDefinition result = null;
270         log.trace("#deletePolicy - starting to update the policy {} on the component {}. ", policyId, componentId);
271         Component component = null;
272         boolean failed = false;
273         try {
274             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
275             return deletePolicy(component, policyId);
276         } catch (ComponentException e) {
277             failed = true;
278             log.error("#deletePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policyId, componentId,
279                 e);
280             throw e;
281         } finally {
282             unlockComponent(shouldLock, failed, component);
283         }
284     }
285
286     public Either<PolicyDefinition, ResponseFormat> undeclarePolicy(ComponentTypeEnum componentType, String componentId, String policyId,
287                                                                     String userId, boolean shouldLock) {
288         Either<PolicyDefinition, ResponseFormat> result = null;
289         log.trace("#undeclarePolicy - starting to undeclare policy {} on component {}. ", policyId, componentId);
290         Wrapper<Component> component = new Wrapper<>();
291         try {
292             validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
293             ComponentParametersView componentParametersView = new ComponentParametersView();
294             componentParametersView.disableAll();
295             componentParametersView.setIgnoreComponentInstances(false);
296             componentParametersView.setIgnoreComponentInstancesProperties(false);
297             componentParametersView.setIgnorePolicies(false);
298             Either<Component, StorageOperationStatus> componentWithFilters = toscaOperationFacade
299                 .getToscaElement(componentId, componentParametersView);
300             if (componentWithFilters.isRight()) {
301                 return Either
302                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentWithFilters.right().value())));
303             }
304             Component containerComponent = componentWithFilters.left().value();
305             Optional<PolicyDefinition> policyCandidate = getPolicyForUndeclaration(policyId, containerComponent);
306             if (policyCandidate.isPresent()) {
307                 result = undeclarePolicy(policyCandidate.get(), containerComponent);
308             }
309             return result;
310         } catch (Exception e) {
311             log.error("#undeclarePolicy - the exception occurred upon update of a policy of type {} for component {}: ", policyId, componentId, e);
312             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, e.getMessage()));
313         } finally {
314             if (result == null || result.isRight()) {
315                 unlockComponent(shouldLock, true, component);
316             } else {
317                 unlockComponent(shouldLock, false, component);
318             }
319         }
320     }
321
322     private Either<PolicyDefinition, ResponseFormat> undeclarePolicy(PolicyDefinition policyDefinition, Component containerComponent) {
323         StorageOperationStatus undeclareStatus = propertyDeclarationOrchestrator.unDeclarePropertiesAsPolicies(containerComponent, policyDefinition);
324         if (undeclareStatus != StorageOperationStatus.OK) {
325             return Either.right(componentsUtils.getResponseFormat(undeclareStatus));
326         } else {
327             return Either.left(policyDefinition);
328         }
329     }
330
331     private Optional<PolicyDefinition> getPolicyForUndeclaration(String policyId, Component component) {
332         Map<String, PolicyDefinition> policies = component.getPolicies();
333         if (MapUtils.isNotEmpty(policies) && policies.containsKey(policyId)) {
334             return Optional.of(policies.get(policyId));
335         }
336         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties =
337             MapUtils.isEmpty(component.getComponentInstancesProperties()) ? new HashMap<>() : component.getComponentInstancesProperties();
338         for (Map.Entry<String, List<ComponentInstanceProperty>> instancePropertyEntry : componentInstancesProperties.entrySet()) {
339             Optional<ComponentInstanceProperty> propertyCandidate = getPropertyForDeclaredPolicy(policyId, instancePropertyEntry.getValue());
340             if (propertyCandidate.isPresent()) {
341                 return Optional.of(PolicyUtils.getDeclaredPolicyDefinition(instancePropertyEntry.getKey(), propertyCandidate.get()));
342             }
343         }
344         return Optional.empty();
345     }
346
347     private Optional<ComponentInstanceProperty> getPropertyForDeclaredPolicy(String policyId,
348                                                                              List<ComponentInstanceProperty> componentInstanceProperties) {
349         for (ComponentInstanceProperty property : componentInstanceProperties) {
350             Optional<GetPolicyValueDataDefinition> getPolicyCandidate = property.safeGetGetPolicyValues().stream()
351                 .filter(getPolicyValue -> getPolicyValue.getPolicyId().equals(policyId)).findAny();
352             if (getPolicyCandidate.isPresent()) {
353                 return Optional.of(property);
354             }
355         }
356         return Optional.empty();
357     }
358
359     public PolicyDefinition updatePolicyTargets(ComponentTypeEnum componentTypeEnum, String componentId, String policyId,
360                                                 Map<PolicyTargetType, List<String>> targets, String userId) {
361         Either<PolicyDefinition, ResponseFormat> result = null;
362         log.debug("updating the policy id {} targets with the components {}. ", policyId, componentId);
363         boolean failed = false;
364         try {
365             //not right error response
366             Component component = validateAndLockComponentAndUserBeforeWriteOperation(componentTypeEnum, componentId, userId, true);
367             return validateAndUpdatePolicyTargets(component, policyId, targets);
368         } catch (ComponentException e) {
369             failed = true;
370             throw e;
371         } finally {
372             unlockComponentById(failed, componentId);
373         }
374     }
375
376     private PolicyDefinition validateAndUpdatePolicyTargets(Component component, String policyId, Map<PolicyTargetType, List<String>> targets) {
377         validateTargetsExistAndTypesCorrect(component.getUniqueId(), targets);
378         return updateTargets(component.getUniqueId(), component.getPolicyById(policyId), targets, policyId);
379     }
380
381     private Component validateTargetsExistAndTypesCorrect(String componentId, Map<PolicyTargetType, List<String>> targets) {
382         Either<Component, StorageOperationStatus> componentEither = toscaOperationFacade.getToscaFullElement(componentId);
383         if (componentEither.isRight()) {
384             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value()));
385         }
386         Component parentComponent = componentEither.left().value();
387         return validateTargetExists(parentComponent, targets.entrySet());
388     }
389
390     private Component validateTargetExists(Component parentComponent, Set<Map.Entry<PolicyTargetType, List<String>>> entries) {
391         for (Map.Entry<PolicyTargetType, List<String>> entry : entries) {
392             checkTargetNotExistOnComponentByType(parentComponent, entry);
393         }
394         return parentComponent;
395     }
396
397     private Component checkTargetNotExistOnComponentByType(Component parentComponent, Map.Entry<PolicyTargetType, List<String>> targetEntry) {
398         for (String id : targetEntry.getValue()) {
399             if (checkNotPresenceInComponentByType(parentComponent, id, targetEntry.getKey().getName())) {
400                 throw new ByActionStatusComponentException(ActionStatus.POLICY_TARGET_DOES_NOT_EXIST, id);
401             }
402         }
403         return parentComponent;
404     }
405
406     private boolean checkNotPresenceInComponentByType(Component parentComponent, String uniqueId, String type) {
407         if (type.equalsIgnoreCase(PolicyTargetType.GROUPS.getName()) && parentComponent.getGroups() != null) {
408             return !parentComponent.getGroupById(uniqueId).isPresent();
409         } else if (type.equalsIgnoreCase(PolicyTargetType.COMPONENT_INSTANCES.getName()) && parentComponent.getComponentInstances() != null) {
410             return !parentComponent.getComponentInstanceById(uniqueId).isPresent();
411         }
412         return true;
413     }
414
415     private PolicyDefinition setPolicyTargets(PolicyDefinition policyDefinition, Map<PolicyTargetType, List<String>> targets) {
416         policyDefinition.setTargets(targets);
417         return policyDefinition;
418     }
419
420     /**
421      * @param componentType the type of the component
422      * @param componentId   the id of the component which the policy resides under
423      * @param policyId      the id of the policy which its properties to return
424      * @param userId        the user id
425      * @return a list of policy properties or an error in a response format
426      */
427     public List<PropertyDataDefinition> getPolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
428         log.debug("#getPolicyProperties - fetching policy properties for component {} and policy {}", componentId, policyId);
429         try {
430             Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
431             return getPolicyById(component, policyId).getProperties();
432         } finally {
433             janusGraphDao.commit();
434         }
435     }
436
437     /**
438      * Updates the policy properties of the component
439      *
440      * @param componentType the type of the component
441      * @param componentId   the id of the component which the policy resides under
442      * @param policyId      the id of the policy which its properties to return
443      * @param properties    a list of policy properties containing updated values
444      * @param userId        the user modifier id
445      * @param shouldLock    the flag defining if the component should be locked
446      * @return a list of policy properties or anerrorin a response format
447      */
448     public List<PropertyDataDefinition> updatePolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId,
449                                                                PropertyDataDefinition[] properties, String userId, boolean shouldLock) {
450         List<PropertyDataDefinition> result;
451         Component component = null;
452         log.trace("#updatePolicyProperties - starting to update properties of the policy {} on the component {}. ", policyId, componentId);
453         boolean failed = true;
454         try {
455             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
456             failed = false;
457             result = setComponentValidateUpdatePolicyProperties(policyId, properties, component);
458         } finally {
459             if (shouldLock && !failed) {
460                 unlockComponent(failed, component);
461             }
462         }
463         return result;
464     }
465
466     @Override
467     public Either<List<PolicyDefinition>, ResponseFormat> declareProperties(String userId, String componentId, ComponentTypeEnum componentTypeEnum,
468                                                                             ComponentInstInputsMap componentInstInputsMap) {
469         return declarePropertiesToPolicies(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
470     }
471
472     private Either<List<PolicyDefinition>, ResponseFormat> declarePropertiesToPolicies(String userId, String componentId,
473                                                                                        ComponentTypeEnum componentTypeEnum,
474                                                                                        ComponentInstInputsMap componentInstInputsMap,
475                                                                                        boolean shouldLock, boolean inTransaction) {
476         Either<List<PolicyDefinition>, ResponseFormat> result = null;
477         org.openecomp.sdc.be.model.Component component = null;
478         try {
479             validateUserExists(userId);
480             ComponentParametersView componentParametersView = new ComponentParametersView();
481             componentParametersView.disableAll();
482             componentParametersView.setIgnoreComponentInstances(false);
483             componentParametersView.setIgnoreComponentInstancesProperties(false);
484             componentParametersView.setIgnorePolicies(false);
485             componentParametersView.setIgnoreUsers(false);
486             component = validateComponentExists(componentId, componentTypeEnum, componentParametersView);
487             if (shouldLock) {
488                 lockComponent(component, DECLARE_PROPERTIES_TO_POLICIES);
489             }
490             validateCanWorkOnComponent(component, userId);
491             Either<List<PolicyDefinition>, StorageOperationStatus> declarePropertiesEither = propertyDeclarationOrchestrator
492                 .declarePropertiesToPolicies(component, componentInstInputsMap);
493             if (declarePropertiesEither.isRight()) {
494                 return Either.right(componentsUtils.getResponseFormat(declarePropertiesEither.right().value()));
495             }
496             result = Either.left(declarePropertiesEither.left().value());
497             return result;
498         } finally {
499             if (!inTransaction) {
500                 commitOrRollback(result);
501             }
502             // unlock resource
503             if (shouldLock && component != null) {
504                 graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
505             }
506         }
507     }
508
509     private List<PropertyDataDefinition> setComponentValidateUpdatePolicyProperties(String policyId, PropertyDataDefinition[] properties,
510                                                                                     Component component) {
511         Set<String> updatedPropertyNames = Arrays.stream(properties).map(PropertyDataDefinition::getName).collect(Collectors.toSet());
512         PolicyDefinition policyDefinition = validateAndUpdatePolicyProperties(component, policyId, properties);
513         return getFilteredProperties(policyDefinition.getProperties(), updatedPropertyNames);
514     }
515
516     private List<PropertyDataDefinition> getFilteredProperties(List<PropertyDataDefinition> all, Set<String> filtered) {
517         return all.stream().filter(pd -> filtered.contains(pd.getName())).collect(Collectors.toList());
518     }
519
520     private void unlockComponent(boolean shouldLock, boolean result, Component component) {
521         if (shouldLock && component != null) {
522             unlockComponent(result, component);
523         }
524     }
525
526     private void unlockComponent(boolean shouldLock, boolean result, Wrapper<Component> component) {
527         if (shouldLock && !component.isEmpty()) {
528             unlockComponent(result, component.getInnerElement());
529         }
530     }
531
532     private PolicyDefinition getPolicyById(Component component, String policyId) {
533         PolicyDefinition policyById = component.getPolicyById(policyId);
534         if (policyById == null) {
535             String cmptId = component.getUniqueId();
536             log.debug("#getPolicyById - policy with id {} does not exist on component with id {}", policyId, cmptId);
537             throw new ByActionStatusComponentException(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, cmptId);
538         }
539         return policyById;
540     }
541
542     private PolicyDefinition createPolicy(String policyTypeName, Component component) {
543         PolicyTypeDefinition policyTypeDefinition = validatePolicyTypeOnCreatePolicy(policyTypeName, component);
544         return addPolicyToComponent(policyTypeDefinition, component);
545     }
546
547     private PolicyDefinition addPolicyToComponent(PolicyTypeDefinition policyType, Component component) {
548         Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent = toscaOperationFacade
549             .associatePolicyToComponent(component.getUniqueId(), new PolicyDefinition(policyType), getNextPolicyCounter(component.getPolicies()));
550         if (associatePolicyToComponent.isRight()) {
551             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(associatePolicyToComponent.right().value()));
552         }
553         return associatePolicyToComponent.left().value();
554     }
555
556     private PolicyTypeDefinition validatePolicyTypeOnCreatePolicy(String policyTypeName, Component component) {
557         Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyTypeByType = policyTypeOperation.getLatestPolicyTypeByType(policyTypeName, component.getModel());
558         if (latestPolicyTypeByType.isRight()) {
559             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestPolicyTypeByType.right().value()));
560         }
561         return validatePolicyTypeNotExcluded(latestPolicyTypeByType.left().value(), component);
562     }
563
564     private PolicyTypeDefinition validatePolicyTypeNotExcluded(PolicyTypeDefinition policyType, Component component) {
565         if (getExcludedPolicyTypesByComponent(component).contains(policyType.getType())) {
566             throw new ByActionStatusComponentException(ActionStatus.EXCLUDED_POLICY_TYPE, policyType.getType(),
567                 getComponentOrResourceTypeName(component));
568         }
569         return policyType;
570     }
571
572     private String getComponentOrResourceTypeName(Component component) {
573         return component.getComponentType() == ComponentTypeEnum.SERVICE ? ComponentTypeEnum.SERVICE.name()
574             : ((Resource) component).getResourceType().name();
575     }
576
577     private Component validateAndLockComponentAndUserBeforeWriteOperation(ComponentTypeEnum componentType, String componentId, String userId,
578                                                                           boolean shouldLock) {
579         Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
580         validateComponentIsTopologyTemplate(component);
581         validateCanWorkOnComponent(component, userId);
582         lockComponent(component, shouldLock, "policyWritingOperation");
583         return component;
584     }
585
586     private Component validateComponentIsTopologyTemplate(Component component) {
587         if (!component.isTopologyTemplate()) {
588             log.error("#validateComponentIsTopologyTemplate - policy association to a component of Tosca type {} is not allowed. ",
589                 component.getToscaType());
590             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_POLICIES,
591                 "#validateAndLockComponentAndUserBeforeWriteOperation", component.getUniqueId(), component.getToscaType());
592         }
593         return component;
594     }
595
596     private Component validateContainerComponentAndUserBeforeReadOperation(ComponentTypeEnum componentType, String componentId, String userId) {
597         log.trace("#validateContainerComponentAndUserBeforeReadOperation - starting to validate the user {} before policy processing. ", userId);
598         validateUserExists(userId);
599         return validateComponentExists(componentType, componentId);
600     }
601
602     private Component validateComponentExists(ComponentTypeEnum componentType, String componentId) {
603         ComponentParametersView filter = new ComponentParametersView(true);
604         filter.setIgnorePolicies(false);
605         filter.setIgnoreUsers(false);
606         filter.setIgnoreComponentInstances(false);
607         filter.setIgnoreGroups(false);
608         return validateComponentExists(componentId, componentType, filter);
609     }
610
611     private PolicyDefinition validateAndUpdatePolicy(Component component, PolicyDefinition policy) {
612         PolicyDefinition policyById = getPolicyById(component, policy.getUniqueId());
613         PolicyDefinition policyDefinition = validateUpdatePolicyBeforeUpdate(policy, policyById, component.getPolicies());
614         return updatePolicyOfComponent(component, policyDefinition);
615     }
616
617     private PolicyDefinition validateAndUpdatePolicyProperties(Component component, String policyId, PropertyDataDefinition[] properties) {
618         PolicyDefinition policyById = getPolicyById(component, policyId);
619         policyById = validateUpdatePolicyPropertiesBeforeUpdate(policyById, properties);
620         return updatePolicyOfComponent(component.getUniqueId(), policyById);
621     }
622
623     private PolicyDefinition updatePolicyOfComponent(String componentId, PolicyDefinition policy) {
624         return toscaOperationFacade.updatePolicyOfComponent(componentId, policy, PromoteVersionEnum.MINOR).left()
625             .on(ce -> componentExceptionPolicyDefinition(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(ce))));
626     }
627
628     private PolicyDefinition validateUpdatePolicyPropertiesBeforeUpdate(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
629         if (CollectionUtils.isEmpty(policy.getProperties())) {
630             log.error(
631                 "#validateUpdatePolicyPropertiesBeforeUpdate - failed to update properites of the policy. Properties were not found on the policy. ");
632             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
633         }
634         return updatePropertyValues(policy, newProperties);
635     }
636
637     private PolicyDefinition updatePropertyValues(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
638         Map<String, PropertyDataDefinition> oldProperties = policy.getProperties().stream()
639             .collect(toMap(PropertyDataDefinition::getName, Function.identity()));
640         for (PropertyDataDefinition newProperty : newProperties) {
641             if (!oldProperties.containsKey(newProperty.getName())) {
642                 log.error("#updatePropertyValues - failed to update properites of the policy {}. Properties were not found on the policy. ",
643                     policy.getName());
644                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getName());
645             }
646             String newPropertyValueEither = updateInputPropertyObjectValue(newProperty);
647             oldProperties.get(newProperty.getName()).setValue(newPropertyValueEither);
648         }
649         return policy;
650     }
651
652     private PolicyDefinition deletePolicy(Component component, String policyId) {
653         PolicyDefinition policyById = getPolicyById(component, policyId);
654         return removePolicyFromComponent(component, policyById);
655     }
656
657     private PolicyDefinition updatePolicyOfComponent(Component component, PolicyDefinition policy) {
658         Either<PolicyDefinition, StorageOperationStatus> updatePolicyRes = toscaOperationFacade
659             .updatePolicyOfComponent(component.getUniqueId(), policy, PromoteVersionEnum.MINOR);
660         if (updatePolicyRes.isRight()) {
661             log.error("#updatePolicyOfComponent - failed to update policy {} of the component {}. The status is {}. ", policy.getUniqueId(),
662                 component.getName(), updatePolicyRes.right().value());
663             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(updatePolicyRes.right().value()));
664         } else {
665             log.trace("#updatePolicyOfComponent - the policy with the name {} was updated. ", updatePolicyRes.left().value().getName());
666             return updatePolicyRes.left().value();
667         }
668     }
669
670     private PolicyDefinition removePolicyFromComponent(Component component, PolicyDefinition policy) {
671         StorageOperationStatus updatePolicyStatus = toscaOperationFacade.removePolicyFromComponent(component.getUniqueId(), policy.getUniqueId());
672         if (updatePolicyStatus != StorageOperationStatus.OK) {
673             log.error("#removePolicyFromComponent - failed to remove policy {} from the component {}. The status is {}. ", policy.getUniqueId(),
674                 component.getName(), updatePolicyStatus);
675             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(updatePolicyStatus));
676         } else {
677             log.trace("#removePolicyFromComponent - the policy with the name {} was deleted. ", updatePolicyStatus);
678             return policy;
679         }
680     }
681
682     private PolicyDefinition validateUpdatePolicyBeforeUpdate(PolicyDefinition recievedPolicy, PolicyDefinition oldPolicy,
683                                                               Map<String, PolicyDefinition> policies) {
684         Either<PolicyDefinition, ActionStatus> policyDefinitionActionStatusEither = validatePolicyFields(recievedPolicy,
685             new PolicyDefinition(oldPolicy), policies);
686         if (policyDefinitionActionStatusEither.isRight()) {
687             throw new ByActionStatusComponentException(policyDefinitionActionStatusEither.right().value(), recievedPolicy.getName());
688         }
689         return policyDefinitionActionStatusEither.left().value();
690     }
691
692     private PolicyDefinition updateTargets(String componentId, PolicyDefinition policy, Map<PolicyTargetType, List<String>> targets,
693                                            String policyId) {
694         if (policy == null) {
695             throw new ByActionStatusComponentException(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, componentId);
696         }
697         PolicyDefinition updatedPolicy = setPolicyTargets(policy, targets);
698         return updatePolicyOfComponent(componentId, updatedPolicy);
699     }
700 }