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