Update vulnerable package dependencies
[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  * ================================================================================
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 java.util.stream.Collectors.toMap;
23 import static org.openecomp.sdc.be.components.validation.PolicyUtils.getExcludedPolicyTypesByComponent;
24 import static org.openecomp.sdc.be.components.validation.PolicyUtils.getNextPolicyCounter;
25 import static org.openecomp.sdc.be.components.validation.PolicyUtils.validatePolicyFields;
26
27 import fj.data.Either;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.EnumMap;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import java.util.Set;
37 import java.util.function.Function;
38 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.apache.commons.collections.MapUtils;
41 import org.apache.commons.lang3.StringUtils;
42 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
43 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
44 import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
45 import org.openecomp.sdc.be.components.validation.PolicyUtils;
46 import org.openecomp.sdc.be.dao.api.ActionStatus;
47 import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
49 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
50 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
52 import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum;
53 import org.openecomp.sdc.be.model.Component;
54 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
55 import org.openecomp.sdc.be.model.ComponentInstance;
56 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
57 import org.openecomp.sdc.be.model.ComponentParametersView;
58 import org.openecomp.sdc.be.model.PolicyDefinition;
59 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
60 import org.openecomp.sdc.be.model.Resource;
61 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
62 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
63 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
64 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
65 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
66 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
67 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
68 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
69 import org.openecomp.sdc.common.datastructure.Wrapper;
70 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
71 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
72 import org.openecomp.sdc.common.log.enums.StatusCode;
73 import org.openecomp.sdc.common.log.wrappers.Logger;
74 import org.openecomp.sdc.exception.ResponseFormat;
75 import org.springframework.beans.factory.annotation.Autowired;
76
77 /**
78  * Provides specified business logic to create, retrieve, update, delete a policy
79  */
80 @org.springframework.stereotype.Component("policyBusinessLogic")
81 public class PolicyBusinessLogic extends BaseBusinessLogic {
82
83     private static final String FAILED_TO_VALIDATE_COMPONENT = "#{} - failed to validate the component {} before policy processing. ";
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<PolicyDefinition, ResponseFormat> createPolicy(ComponentTypeEnum componentType, String componentId, String policyTypeName, String userId, boolean shouldLock) {
202
203         Either<PolicyDefinition, ResponseFormat> result = null;
204         log.trace("#createPolicy - starting to create policy of the type {} on the component {}. ", policyTypeName, componentId);
205         Wrapper<Component> component = new Wrapper<>();
206         try {
207             result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock)
208                     .left()
209                     .bind(c -> {
210                         component.setInnerElement(c);
211                         return createPolicy(policyTypeName, c);
212                     });
213         } catch (Exception e) {
214             if (ComponentException.class.equals(e.getClass())) {
215                 throw e;
216             }
217             log.error("#createPolicy - the exception  occurred upon creation of a policy of the type {} for the component {}: ", policyTypeName, componentId, e);
218             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
219         } finally {
220             //TODO Andrey result = boolean
221             unlockComponent(shouldLock, result, component);
222         }
223         return result;
224     }*/
225     public Either<List<PolicyDefinition>, ResponseFormat> getPoliciesList(ComponentTypeEnum componentType, String componentId, String userId) {
226         Either<List<PolicyDefinition>, ResponseFormat> result;
227         log.trace("#getPolicies - starting to retrieve policies of component {}. ", componentId);
228         try {
229             Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
230             result = Either.left(component.resolvePoliciesList());
231         } catch (Exception e) {
232             log.error("#getPolicy - the exception occurred upon retrieving policies list of component {}: ", componentId, e);
233             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
234         }
235         return result;
236     }
237
238     /**
239      * Retrieves the policy of the component by UniqueId
240      *
241      * @param componentType the type of the component
242      * @param componentId   the ID of the component
243      * @param policyId      the ID of the policy
244      * @param userId        the ID of the user
245      * @return either policy or error response
246      */
247     public PolicyDefinition getPolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
248         log.trace("#getPolicy - starting to retrieve the policy {} of the component {}. ", policyId, componentId);
249         Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
250         return getPolicyById(component, policyId);
251     }
252     /*public Either<PolicyDefinition, ResponseFormat> getPolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
253         Either<PolicyDefinition, ResponseFormat> result;
254         log.trace("#getPolicy - starting to retrieve the policy {} of the component {}. ", policyId, componentId);
255         try {
256             result = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
257                     .left()
258                     .bind(c -> getPolicyById(c, policyId));
259         } catch (Exception e) {
260             log.error("#getPolicy - the exception occurred upon retrieving the policy {} of the component {}: ", policyId, componentId, e);
261             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
262         }
263         return result;
264     }*/
265
266     /**
267      * Updates the policy of the component
268      *
269      * @param componentType the type of the component
270      * @param componentId   the id of the component which the policy resides under
271      * @param policy        the policy to update
272      * @param userId        the user modifier id
273      * @param shouldLock    the flag defining if the component should be locked
274      * @return a policy or an error in a response format
275      */
276     public PolicyDefinition updatePolicy(ComponentTypeEnum componentType, String componentId, PolicyDefinition policy, String userId,
277                                          boolean shouldLock) {
278         Component component = null;
279         boolean failed = false;
280         log.trace("#updatePolicy - starting to update the policy {} on the component {}. ", policy.getUniqueId(), componentId);
281         try {
282             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
283             return validateAndUpdatePolicy(component, policy);
284         } catch (ComponentException e) {
285             failed = true;
286             log.error("#updatePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policy.getUniqueId(),
287                 componentId, e);
288             throw e;
289         } finally {
290             //TODO Andrey result = boolean
291             unlockComponent(shouldLock, failed, component);
292         }
293     }
294     /*public Either<PolicyDefinition, ResponseFormat> updatePolicy(ComponentTypeEnum componentType, String componentId, PolicyDefinition policy, String userId, boolean shouldLock) {
295         Either<PolicyDefinition, ResponseFormat> result = null;
296         log.trace("#updatePolicy - starting to update the policy {} on the component {}. ", policy.getUniqueId(), componentId);
297         Wrapper<Component> component = new Wrapper<>();
298         try {
299             result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock)
300                     .left()
301                     .bind(c -> {
302                         component.setInnerElement(c);
303                         return validateAndUpdatePolicy(c, policy);
304                     });
305         } catch (Exception e) {
306             log.error("#updatePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policy.getUniqueId(), componentId, e);
307             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
308         } finally {
309             //TODO Andrey result = boolean
310             unlockComponent(shouldLock, result, component);
311         }
312         return result;
313     }*/
314
315     /**
316      * Deletes the policy from the component
317      *
318      * @param componentType the type of the component
319      * @param componentId   the id of the component which the policy resides under
320      * @param policyId      the id of the policy which its properties to return
321      * @param userId        the user modifier id
322      * @param shouldLock    the flag defining if the component should be locked
323      * @return a policy or an error in a response format
324      */
325     public PolicyDefinition deletePolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId, boolean shouldLock) {
326         PolicyDefinition result = null;
327         log.trace("#deletePolicy - starting to update the policy {} on the component {}. ", policyId, componentId);
328         Component component = null;
329         boolean failed = false;
330         try {
331             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
332             return deletePolicy(component, policyId);
333         } catch (ComponentException e) {
334             failed = true;
335             log.error("#deletePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policyId, componentId,
336                 e);
337             throw e;
338         } finally {
339             unlockComponent(shouldLock, failed, component);
340         }
341     }
342
343     /*public Either<PolicyDefinition, ResponseFormat> deletePolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId, boolean shouldLock) {
344         Either<PolicyDefinition, ResponseFormat> result = null;
345         log.trace("#deletePolicy - starting to update the policy {} on the component {}. ", policyId, componentId);
346         Wrapper<Component> component = new Wrapper<>();
347         try {
348             Either<Component, ResponseFormat> componentEither =
349                     validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
350             if (componentEither.isRight()) {
351                 return Either.right(componentEither.right().value());
352             }
353
354             ComponentParametersView componentParametersView = new ComponentParametersView();
355             componentParametersView.disableAll();
356             componentParametersView.setIgnoreComponentInstances(false);
357             componentParametersView.setIgnoreComponentInstancesProperties(false);
358             componentParametersView.setIgnorePolicies(false);
359             componentParametersView.setIgnoreProperties(false);
360
361             Either<Component, StorageOperationStatus> componentWithFilters =
362                     toscaOperationFacade.getToscaElement(componentId, componentParametersView);
363             if (componentWithFilters.isRight()) {
364                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentWithFilters.right().value())));
365             }
366
367             Component containerComponent = componentWithFilters.left().value();
368             component.setInnerElement(containerComponent);
369             result = deletePolicy(containerComponent, policyId);
370
371             if(result.isRight()) {
372                 log.error("#deletePolicy - could not delete policy of the type {} for the component {}: ", policyId, componentId);
373                 return result;
374             }
375
376             PolicyDefinition policyToDelete = result.left().value();
377
378             StorageOperationStatus storageOperationStatus = propertyDeclarationOrchestrator.unDeclarePropertiesAsPolicies(
379                     containerComponent, policyToDelete);
380             if (storageOperationStatus != StorageOperationStatus.OK) {
381                 log.debug("Component id: {} update properties declared as policy for policy id: {} failed", componentId, policyId);
382                 return Either.right(componentsUtils.getResponseFormat(componentsUtils
383                                                                                       .convertFromStorageResponse(storageOperationStatus), containerComponent.getName()));
384             }
385
386             return result;
387         } catch (Exception e) {
388             log.error("#deletePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policyId, componentId, e);
389             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, e.getMessage()));
390         } finally {
391             unlockComponent(shouldLock, result, component);
392         }
393     }*/
394     public Either<PolicyDefinition, ResponseFormat> undeclarePolicy(ComponentTypeEnum componentType, String componentId, String policyId,
395                                                                     String userId, boolean shouldLock) {
396         Either<PolicyDefinition, ResponseFormat> result = null;
397         log.trace("#undeclarePolicy - starting to undeclare policy {} on component {}. ", policyId, componentId);
398         Wrapper<Component> component = new Wrapper<>();
399         try {
400             validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
401             ComponentParametersView componentParametersView = new ComponentParametersView();
402             componentParametersView.disableAll();
403             componentParametersView.setIgnoreComponentInstances(false);
404             componentParametersView.setIgnoreComponentInstancesProperties(false);
405             componentParametersView.setIgnorePolicies(false);
406             Either<Component, StorageOperationStatus> componentWithFilters = toscaOperationFacade
407                 .getToscaElement(componentId, componentParametersView);
408             if (componentWithFilters.isRight()) {
409                 return Either
410                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentWithFilters.right().value())));
411             }
412             Component containerComponent = componentWithFilters.left().value();
413             Optional<PolicyDefinition> policyCandidate = getPolicyForUndeclaration(policyId, containerComponent);
414             if (policyCandidate.isPresent()) {
415                 result = undeclarePolicy(policyCandidate.get(), containerComponent);
416             }
417             return result;
418         } catch (Exception e) {
419             log.error("#undeclarePolicy - the exception occurred upon update of a policy of type {} for component {}: ", policyId, componentId, e);
420             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, e.getMessage()));
421         } finally {
422             if (result == null || result.isRight()) {
423                 unlockComponent(shouldLock, true, component);
424             } else {
425                 unlockComponent(shouldLock, false, component);
426             }
427         }
428     }
429
430     private Either<PolicyDefinition, ResponseFormat> undeclarePolicy(PolicyDefinition policyDefinition, Component containerComponent) {
431         StorageOperationStatus undeclareStatus = propertyDeclarationOrchestrator.unDeclarePropertiesAsPolicies(containerComponent, policyDefinition);
432         if (undeclareStatus != StorageOperationStatus.OK) {
433             return Either.right(componentsUtils.getResponseFormat(undeclareStatus));
434         } else {
435             return Either.left(policyDefinition);
436         }
437     }
438
439     private Optional<PolicyDefinition> getPolicyForUndeclaration(String policyId, Component component) {
440         Map<String, PolicyDefinition> policies = component.getPolicies();
441         if (MapUtils.isNotEmpty(policies) && policies.containsKey(policyId)) {
442             return Optional.of(policies.get(policyId));
443         }
444         Map<String, List<ComponentInstanceProperty>> componentInstancesProperties =
445             MapUtils.isEmpty(component.getComponentInstancesProperties()) ? new HashMap<>() : component.getComponentInstancesProperties();
446         for (Map.Entry<String, List<ComponentInstanceProperty>> instancePropertyEntry : componentInstancesProperties.entrySet()) {
447             Optional<ComponentInstanceProperty> propertyCandidate = getPropertyForDeclaredPolicy(policyId, instancePropertyEntry.getValue());
448             if (propertyCandidate.isPresent()) {
449                 return Optional.of(PolicyUtils.getDeclaredPolicyDefinition(instancePropertyEntry.getKey(), propertyCandidate.get()));
450             }
451         }
452         return Optional.empty();
453     }
454
455     private Optional<ComponentInstanceProperty> getPropertyForDeclaredPolicy(String policyId,
456                                                                              List<ComponentInstanceProperty> componentInstanceProperties) {
457         for (ComponentInstanceProperty property : componentInstanceProperties) {
458             Optional<GetPolicyValueDataDefinition> getPolicyCandidate = property.safeGetGetPolicyValues().stream()
459                 .filter(getPolicyValue -> getPolicyValue.getPolicyId().equals(policyId)).findAny();
460             if (getPolicyCandidate.isPresent()) {
461                 return Optional.of(property);
462             }
463         }
464         return Optional.empty();
465     }
466
467     public PolicyDefinition updatePolicyTargets(ComponentTypeEnum componentTypeEnum, String componentId, String policyId,
468                                                 Map<PolicyTargetType, List<String>> targets, String userId) {
469         Either<PolicyDefinition, ResponseFormat> result = null;
470         log.debug("updating the policy id {} targets with the components {}. ", policyId, componentId);
471         boolean failed = false;
472         try {
473             //not right error response
474             Component component = validateAndLockComponentAndUserBeforeWriteOperation(componentTypeEnum, componentId, userId, true);
475             return validateAndUpdatePolicyTargets(component, policyId, targets);
476         } catch (ComponentException e) {
477             failed = true;
478             throw e;
479         } finally {
480             unlockComponentById(failed, componentId);
481         }
482     }
483
484     private PolicyDefinition validateAndUpdatePolicyTargets(Component component, String policyId, Map<PolicyTargetType, List<String>> targets) {
485         validateTargetsExistAndTypesCorrect(component.getUniqueId(), targets);
486         return updateTargets(component.getUniqueId(), component.getPolicyById(policyId), targets, policyId);
487     }
488
489     private Component validateTargetsExistAndTypesCorrect(String componentId, Map<PolicyTargetType, List<String>> targets) {
490         Either<Component, StorageOperationStatus> componentEither = toscaOperationFacade.getToscaFullElement(componentId);
491         if (componentEither.isRight()) {
492             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value()));
493         }
494         Component parentComponent = componentEither.left().value();
495         return validateTargetExists(parentComponent, targets.entrySet());
496     }
497
498     private Component validateTargetExists(Component parentComponent, Set<Map.Entry<PolicyTargetType, List<String>>> entries) {
499         for (Map.Entry<PolicyTargetType, List<String>> entry : entries) {
500             checkTargetNotExistOnComponentByType(parentComponent, entry);
501         }
502         return parentComponent;
503     }
504
505     private Component checkTargetNotExistOnComponentByType(Component parentComponent, Map.Entry<PolicyTargetType, List<String>> targetEntry) {
506         for (String id : targetEntry.getValue()) {
507             if (checkNotPresenceInComponentByType(parentComponent, id, targetEntry.getKey().getName())) {
508                 throw new ByActionStatusComponentException(ActionStatus.POLICY_TARGET_DOES_NOT_EXIST, id);
509             }
510         }
511         return parentComponent;
512     }
513
514     private boolean checkNotPresenceInComponentByType(Component parentComponent, String uniqueId, String type) {
515         if (type.equalsIgnoreCase(PolicyTargetType.GROUPS.getName()) && parentComponent.getGroups() != null) {
516             return !parentComponent.getGroupById(uniqueId).isPresent();
517         } else if (type.equalsIgnoreCase(PolicyTargetType.COMPONENT_INSTANCES.getName()) && parentComponent.getComponentInstances() != null) {
518             return !parentComponent.getComponentInstanceById(uniqueId).isPresent();
519         }
520         return true;
521     }
522
523     private PolicyDefinition setPolicyTargets(PolicyDefinition policyDefinition, Map<PolicyTargetType, List<String>> targets) {
524         policyDefinition.setTargets(targets);
525         return policyDefinition;
526     }
527
528     /**
529      * @param componentType the type of the component
530      * @param componentId   the id of the component which the policy resides under
531      * @param policyId      the id of the policy which its properties to return
532      * @param userId        the user id
533      * @return a list of policy properties or an error in a response format
534      */
535     public List<PropertyDataDefinition> getPolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
536         log.debug("#getPolicyProperties - fetching policy properties for component {} and policy {}", componentId, policyId);
537         try {
538             Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
539             return getPolicyById(component, policyId).getProperties();
540         } finally {
541             janusGraphDao.commit();
542         }
543     }
544     /*public Either<List<PropertyDataDefinition>, ResponseFormat> getPolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
545         log.debug("#getPolicyProperties - fetching policy properties for component {} and policy {}", componentId, policyId);
546         try {
547             return validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
548                     .left()
549                     .bind(cmpt -> getPolicyById(cmpt, policyId)).left().map(PolicyDataDefinition::getProperties);
550         } finally {
551             janusGraphDao.commit();
552         }
553     }*/
554
555     /**
556      * Updates the policy properties of the component
557      *
558      * @param componentType the type of the component
559      * @param componentId   the id of the component which the policy resides under
560      * @param policyId      the id of the policy which its properties to return
561      * @param properties    a list of policy properties containing updated values
562      * @param userId        the user modifier id
563      * @param shouldLock    the flag defining if the component should be locked
564      * @return a list of policy properties or anerrorin a response format
565      */
566     public List<PropertyDataDefinition> updatePolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId,
567                                                                PropertyDataDefinition[] properties, String userId, boolean shouldLock) {
568         List<PropertyDataDefinition> result;
569         Component component = null;
570         log.trace("#updatePolicyProperties - starting to update properties of the policy {} on the component {}. ", policyId, componentId);
571         boolean failed = true;
572         try {
573             component = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock);
574             failed = false;
575             result = setComponentValidateUpdatePolicyProperties(policyId, properties, component);
576         } finally {
577             if (shouldLock && !failed) {
578                 unlockComponent(failed, component);
579             }
580         }
581         return result;
582     }
583
584     @Override
585     public Either<List<PolicyDefinition>, ResponseFormat> declareProperties(String userId, String componentId, ComponentTypeEnum componentTypeEnum,
586                                                                             ComponentInstInputsMap componentInstInputsMap) {
587         return declarePropertiesToPolicies(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
588     }
589
590     private Either<List<PolicyDefinition>, ResponseFormat> declarePropertiesToPolicies(String userId, String componentId,
591                                                                                        ComponentTypeEnum componentTypeEnum,
592                                                                                        ComponentInstInputsMap componentInstInputsMap,
593                                                                                        boolean shouldLock, boolean inTransaction) {
594         Either<List<PolicyDefinition>, ResponseFormat> result = null;
595         org.openecomp.sdc.be.model.Component component = null;
596         try {
597             validateUserExists(userId);
598             ComponentParametersView componentParametersView = new ComponentParametersView();
599             componentParametersView.disableAll();
600             componentParametersView.setIgnoreComponentInstances(false);
601             componentParametersView.setIgnoreComponentInstancesProperties(false);
602             componentParametersView.setIgnorePolicies(false);
603             componentParametersView.setIgnoreUsers(false);
604             component = validateComponentExists(componentId, componentTypeEnum, componentParametersView);
605             if (shouldLock) {
606                 lockComponent(component, DECLARE_PROPERTIES_TO_POLICIES);
607             }
608             validateCanWorkOnComponent(component, userId);
609             Either<List<PolicyDefinition>, StorageOperationStatus> declarePropertiesEither = propertyDeclarationOrchestrator
610                 .declarePropertiesToPolicies(component, componentInstInputsMap);
611             if (declarePropertiesEither.isRight()) {
612                 return Either.right(componentsUtils.getResponseFormat(declarePropertiesEither.right().value()));
613             }
614             result = Either.left(declarePropertiesEither.left().value());
615             return result;
616         } finally {
617             if (!inTransaction) {
618                 commitOrRollback(result);
619             }
620             // unlock resource
621             if (shouldLock && component != null) {
622                 graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
623             }
624         }
625     }
626
627     private List<PropertyDataDefinition> setComponentValidateUpdatePolicyProperties(String policyId, PropertyDataDefinition[] properties,
628                                                                                     Component component) {
629         Set<String> updatedPropertyNames = Arrays.stream(properties).map(PropertyDataDefinition::getName).collect(Collectors.toSet());
630         PolicyDefinition policyDefinition = validateAndUpdatePolicyProperties(component, policyId, properties);
631         return getFilteredProperties(policyDefinition.getProperties(), updatedPropertyNames);
632     }
633
634     private List<PropertyDataDefinition> getFilteredProperties(List<PropertyDataDefinition> all, Set<String> filtered) {
635         return all.stream().filter(pd -> filtered.contains(pd.getName())).collect(Collectors.toList());
636     }
637
638     private void unlockComponent(boolean shouldLock, boolean result, Component component) {
639         if (shouldLock && component != null) {
640             unlockComponent(result, component);
641         }
642     }
643
644     private void unlockComponent(boolean shouldLock, boolean result, Wrapper<Component> component) {
645         if (shouldLock && !component.isEmpty()) {
646             unlockComponent(result, component.getInnerElement());
647         }
648     }
649
650     private PolicyDefinition getPolicyById(Component component, String policyId) {
651         PolicyDefinition policyById = component.getPolicyById(policyId);
652         if (policyById == null) {
653             String cmptId = component.getUniqueId();
654             log.debug("#getPolicyById - policy with id {} does not exist on component with id {}", policyId, cmptId);
655             throw new ByActionStatusComponentException(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, cmptId);
656         }
657         return policyById;
658     }
659
660     private PolicyDefinition createPolicy(String policyTypeName, Component component) {
661         PolicyTypeDefinition policyTypeDefinition = validatePolicyTypeOnCreatePolicy(policyTypeName, component);
662         return addPolicyToComponent(policyTypeDefinition, component);
663     }
664
665     /*private Either<PolicyDefinition, ResponseFormat> createPolicy(String policyTypeName, Component component) {
666         return validatePolicyTypeOnCreatePolicy(policyTypeName, component).left().bind(type -> addPolicyToComponent(type, component));
667     }*/
668     private PolicyDefinition addPolicyToComponent(PolicyTypeDefinition policyType, Component component) {
669         Either<PolicyDefinition, StorageOperationStatus> associatePolicyToComponent = toscaOperationFacade
670             .associatePolicyToComponent(component.getUniqueId(), new PolicyDefinition(policyType), getNextPolicyCounter(component.getPolicies()));
671         if (associatePolicyToComponent.isRight()) {
672             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(associatePolicyToComponent.right().value()));
673         }
674         return associatePolicyToComponent.left().value();
675     }
676
677     /*private Either<PolicyDefinition, ResponseFormat> addPolicyToComponent(PolicyTypeDefinition policyType, Component component) {
678         return toscaOperationFacade.associatePolicyToComponent(component.getUniqueId(), new PolicyDefinition(policyType), getNextPolicyCounter(component.getPolicies()))
679                 .either(Either::left, r -> Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(r))));
680     }*/
681     private PolicyTypeDefinition validatePolicyTypeOnCreatePolicy(String policyTypeName, Component component) {
682         Either<PolicyTypeDefinition, StorageOperationStatus> latestPolicyTypeByType = policyTypeOperation.getLatestPolicyTypeByType(policyTypeName);
683         if (latestPolicyTypeByType.isRight()) {
684             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(latestPolicyTypeByType.right().value()));
685         }
686         return validatePolicyTypeNotExcluded(latestPolicyTypeByType.left().value(), component);
687     }
688
689     /*private Either<PolicyTypeDefinition, ResponseFormat> validatePolicyTypeOnCreatePolicy(String policyTypeName, Component component) {
690         return policyTypeOperation.getLatestPolicyTypeByType(policyTypeName)
691                 .either(l -> validatePolicyTypeNotExcluded(l, component), r -> Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(r))));
692     }*/
693     private PolicyTypeDefinition validatePolicyTypeNotExcluded(PolicyTypeDefinition policyType, Component component) {
694         if (getExcludedPolicyTypesByComponent(component).contains(policyType.getType())) {
695             throw new ByActionStatusComponentException(ActionStatus.EXCLUDED_POLICY_TYPE, policyType.getType(),
696                 getComponentOrResourceTypeName(component));
697         }
698         return policyType;
699     }
700
701     private String getComponentOrResourceTypeName(Component component) {
702         return component.getComponentType() == ComponentTypeEnum.SERVICE ? ComponentTypeEnum.SERVICE.name()
703             : ((Resource) component).getResourceType().name();
704     }
705
706     private Component validateAndLockComponentAndUserBeforeWriteOperation(ComponentTypeEnum componentType, String componentId, String userId,
707                                                                           boolean shouldLock) {
708         Component component = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId);
709         validateComponentIsTopologyTemplate(component);
710         validateCanWorkOnComponent(component, userId);
711         lockComponent(component, shouldLock, "policyWritingOperation");
712         return component;
713     }
714
715     /*private Either<Component, ResponseFormat> validateAndLockComponentAndUserBeforeWriteOperation(ComponentTypeEnum componentType, String componentId, String userId, boolean shouldLock) {
716         Wrapper<Component> component = new Wrapper<>();
717         return validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
718                 .left()
719                 .bind(this::validateComponentIsTopologyTemplate)
720                 .left()
721                 .bind(c -> {
722                     component.setInnerElement(c);
723                     validateCanWorkOnComponent(c, userId);
724                     return Either.left(component);
725                 })
726                 .left()
727                 .bind(l -> lockComponent(component.getInnerElement(), shouldLock, "policyWritingOperation"))
728                 .either(l -> Either.left(component.getInnerElement()), r -> {
729                     log.error(FAILED_TO_VALIDATE_COMPONENT, componentId);
730                     return Either.right(r);
731                 });
732     }*/
733     private Component validateComponentIsTopologyTemplate(Component component) {
734         if (!component.isTopologyTemplate()) {
735             log.error("#validateComponentIsTopologyTemplate - policy association to a component of Tosca type {} is not allowed. ",
736                 component.getToscaType());
737             throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_POLICIES,
738                 "#validateAndLockComponentAndUserBeforeWriteOperation", component.getUniqueId(), component.getToscaType());
739         }
740         return component;
741     }
742
743     /*private Either<Component, ResponseFormat> validateComponentIsTopologyTemplate(Component component) {
744         if (!component.isTopologyTemplate()) {
745             log.error("#validateComponentIsTopologyTemplate - policy association to a component of Tosca type {} is not allowed. ", component.getToscaType());
746             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CANNOT_CONTAIN_POLICIES, "#validateAndLockComponentAndUserBeforeWriteOperation", component.getUniqueId(), component.getToscaType()));
747         }
748         return Either.left(component);
749     }*/
750     private Component validateContainerComponentAndUserBeforeReadOperation(ComponentTypeEnum componentType, String componentId, String userId) {
751         log.trace("#validateContainerComponentAndUserBeforeReadOperation - starting to validate the user {} before policy processing. ", userId);
752         validateUserExists(userId);
753         return validateComponentExists(componentType, componentId);
754     }
755
756     private Component validateComponentExists(ComponentTypeEnum componentType, String componentId) {
757         ComponentParametersView filter = new ComponentParametersView(true);
758         filter.setIgnorePolicies(false);
759         filter.setIgnoreUsers(false);
760         filter.setIgnoreComponentInstances(false);
761         filter.setIgnoreGroups(false);
762         return validateComponentExists(componentId, componentType, filter);
763     }
764
765     private PolicyDefinition validateAndUpdatePolicy(Component component, PolicyDefinition policy) {
766         PolicyDefinition policyById = getPolicyById(component, policy.getUniqueId());
767         PolicyDefinition policyDefinition = validateUpdatePolicyBeforeUpdate(policy, policyById, component.getPolicies());
768         return updatePolicyOfComponent(component, policyDefinition);
769     }
770
771     /*private Either<PolicyDefinition, ResponseFormat> validateAndUpdatePolicy(Component component, PolicyDefinition policy) {
772         return getPolicyById(component, policy.getUniqueId())
773                 .left()
774                 .bind(np -> validateUpdatePolicyBeforeUpdate(policy, np, component.getPolicies()))
775                 .left()
776                 .bind(p -> updatePolicyOfComponent(component, p));
777     }*/
778     private PolicyDefinition validateAndUpdatePolicyProperties(Component component, String policyId, PropertyDataDefinition[] properties) {
779         PolicyDefinition policyById = getPolicyById(component, policyId);
780         policyById = validateUpdatePolicyPropertiesBeforeUpdate(policyById, properties);
781         return updatePolicyOfComponent(component.getUniqueId(), policyById);
782     }
783
784     private PolicyDefinition updatePolicyOfComponent(String componentId, PolicyDefinition policy) {
785         return toscaOperationFacade.updatePolicyOfComponent(componentId, policy, PromoteVersionEnum.MINOR).left()
786             .on(ce -> componentExceptionPolicyDefinition(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(ce))));
787     }
788
789     private PolicyDefinition validateUpdatePolicyPropertiesBeforeUpdate(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
790         if (CollectionUtils.isEmpty(policy.getProperties())) {
791             log.error(
792                 "#validateUpdatePolicyPropertiesBeforeUpdate - failed to update properites of the policy. Properties were not found on the policy. ");
793             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND);
794         }
795         return updatePropertyValues(policy, newProperties);
796     }
797
798     private PolicyDefinition updatePropertyValues(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
799         Map<String, PropertyDataDefinition> oldProperties = policy.getProperties().stream()
800             .collect(toMap(PropertyDataDefinition::getName, Function.identity()));
801         for (PropertyDataDefinition newProperty : newProperties) {
802             if (!oldProperties.containsKey(newProperty.getName())) {
803                 log.error("#updatePropertyValues - failed to update properites of the policy {}. Properties were not found on the policy. ",
804                     policy.getName());
805                 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getName());
806             }
807             String newPropertyValueEither = updateInputPropertyObjectValue(newProperty);
808             oldProperties.get(newProperty.getName()).setValue(newPropertyValueEither);
809         }
810         return policy;
811     }
812
813     private PolicyDefinition deletePolicy(Component component, String policyId) {
814         PolicyDefinition policyById = getPolicyById(component, policyId);
815         return removePolicyFromComponent(component, policyById);
816     }
817
818     private PolicyDefinition updatePolicyOfComponent(Component component, PolicyDefinition policy) {
819         Either<PolicyDefinition, StorageOperationStatus> updatePolicyRes = toscaOperationFacade
820             .updatePolicyOfComponent(component.getUniqueId(), policy, PromoteVersionEnum.MINOR);
821         if (updatePolicyRes.isRight()) {
822             log.error("#updatePolicyOfComponent - failed to update policy {} of the component {}. The status is {}. ", policy.getUniqueId(),
823                 component.getName(), updatePolicyRes.right().value());
824             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(updatePolicyRes.right().value()));
825         } else {
826             log.trace("#updatePolicyOfComponent - the policy with the name {} was updated. ", updatePolicyRes.left().value().getName());
827             return updatePolicyRes.left().value();
828         }
829     }
830
831     private PolicyDefinition removePolicyFromComponent(Component component, PolicyDefinition policy) {
832         StorageOperationStatus updatePolicyStatus = toscaOperationFacade.removePolicyFromComponent(component.getUniqueId(), policy.getUniqueId());
833         if (updatePolicyStatus != StorageOperationStatus.OK) {
834             log.error("#removePolicyFromComponent - failed to remove policy {} from the component {}. The status is {}. ", policy.getUniqueId(),
835                 component.getName(), updatePolicyStatus);
836             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(updatePolicyStatus));
837         } else {
838             log.trace("#removePolicyFromComponent - the policy with the name {} was deleted. ", updatePolicyStatus);
839             return policy;
840         }
841     }
842
843     private PolicyDefinition validateUpdatePolicyBeforeUpdate(PolicyDefinition recievedPolicy, PolicyDefinition oldPolicy,
844                                                               Map<String, PolicyDefinition> policies) {
845         Either<PolicyDefinition, ActionStatus> policyDefinitionActionStatusEither = validatePolicyFields(recievedPolicy,
846             new PolicyDefinition(oldPolicy), policies);
847         if (policyDefinitionActionStatusEither.isRight()) {
848             throw new ByActionStatusComponentException(policyDefinitionActionStatusEither.right().value(), recievedPolicy.getName());
849         }
850         return policyDefinitionActionStatusEither.left().value();
851     }
852
853     /*private Either<PolicyDefinition, ResponseFormat> validateUpdatePolicyBeforeUpdate(PolicyDefinition recievedPolicy, PolicyDefinition oldPolicy, Map<String, PolicyDefinition> policies) {
854         return validatePolicyFields(recievedPolicy, new PolicyDefinition(oldPolicy), policies)
855                 .right()
856                 .bind(r -> Either.right(componentsUtils.getResponseFormat(r, recievedPolicy.getName())));
857     }*/
858     private PolicyDefinition updateTargets(String componentId, PolicyDefinition policy, Map<PolicyTargetType, List<String>> targets,
859                                            String policyId) {
860         if (policy == null) {
861             throw new ByActionStatusComponentException(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, componentId);
862         }
863         PolicyDefinition updatedPolicy = setPolicyTargets(policy, targets);
864         return updatePolicyOfComponent(componentId, updatedPolicy);
865     }
866 }