1 package org.openecomp.sdc.be.components.impl;
4 import org.apache.commons.collections.CollectionUtils;
5 import org.openecomp.sdc.be.dao.api.ActionStatus;
6 import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
7 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
8 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
9 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
10 import org.openecomp.sdc.be.model.*;
11 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
12 import org.openecomp.sdc.common.datastructure.Wrapper;
13 import org.openecomp.sdc.common.log.wrappers.Logger;
14 import org.openecomp.sdc.exception.ResponseFormat;
16 import java.util.Arrays;
17 import java.util.List;
20 import java.util.function.Function;
21 import java.util.stream.Collectors;
23 import static java.util.stream.Collectors.toMap;
24 import static org.openecomp.sdc.be.components.validation.PolicyUtils.*;
27 * Provides specified business logic to create, retrieve, update, delete a policy
29 @org.springframework.stereotype.Component("policyBusinessLogic")
30 public class PolicyBusinessLogic extends BaseBusinessLogic {
32 private static final String FAILED_TO_VALIDATE_COMPONENT = "#{} - failed to validate the component {} before policy processing. ";
33 private static final Logger log = Logger.getLogger(PolicyBusinessLogic.class);
36 * Adds the newly created policy of the specified type to the component
38 * @param componentType the type of the component
39 * @param componentId the id of the component which the policy resides under
40 * @param policyTypeName the name of the policy type
41 * @param userId the user creator id
42 * @param shouldLock the flag defining if the component should be locked
43 * @return a policy or an error in a response format
46 public Either<PolicyDefinition, ResponseFormat> createPolicy(ComponentTypeEnum componentType, String componentId, String policyTypeName, String userId, boolean shouldLock) {
48 Either<PolicyDefinition, ResponseFormat> result = null;
49 log.trace("#createPolicy - starting to create policy of the type {} on the component {}. ", policyTypeName, componentId);
50 Wrapper<Component> component = new Wrapper<>();
52 result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock)
55 component.setInnerElement(c);
56 return createPolicy(policyTypeName, c);
58 } catch (Exception e) {
59 log.error("#createPolicy - the exception occurred upon creation of a policy of the type {} for the component {}: ", policyTypeName, componentId, e);
60 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
63 unlockComponent(shouldLock, result, component);
69 * Retrieves the policy of the component by UniqueId
71 * @param componentType the type of the component
72 * @param componentId the ID of the component
73 * @param policyId the ID of the policy
74 * @param userId the ID of the user
75 * @return either policy or error response
77 public Either<PolicyDefinition, ResponseFormat> getPolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
78 Either<PolicyDefinition, ResponseFormat> result;
79 log.trace("#getPolicy - starting to retrieve the policy {} of the component {}. ", policyId, componentId);
81 result = validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
83 .bind(c -> getPolicyById(c, policyId));
84 } catch (Exception e) {
85 log.error("#getPolicy - the exception occurred upon retrieving the policy {} of the component {}: ", policyId, componentId, e);
86 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
92 * Updates the policy of the component
94 * @param componentType the type of the component
95 * @param componentId the id of the component which the policy resides under
96 * @param policy the policy to update
97 * @param userId the user modifier id
98 * @param shouldLock the flag defining if the component should be locked
99 * @return a policy or an error in a response format
101 public Either<PolicyDefinition, ResponseFormat> updatePolicy(ComponentTypeEnum componentType, String componentId, PolicyDefinition policy, String userId, boolean shouldLock) {
102 Either<PolicyDefinition, ResponseFormat> result = null;
103 log.trace("#updatePolicy - starting to update the policy {} on the component {}. ", policy.getUniqueId(), componentId);
104 Wrapper<Component> component = new Wrapper<>();
106 result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock)
109 component.setInnerElement(c);
110 return validateAndUpdatePolicy(c, policy);
112 } catch (Exception e) {
113 log.error("#updatePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policy.getUniqueId(), componentId, e);
114 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
116 unlockComponent(shouldLock, result, component);
122 * Deletes the policy from the component
124 * @param componentType the type of the component
125 * @param componentId the id of the component which the policy resides under
126 * @param policyId the id of the policy which its properties to return
127 * @param userId the user modifier id
128 * @param shouldLock the flag defining if the component should be locked
129 * @return a policy or an error in a response format
131 public Either<PolicyDefinition, ResponseFormat> deletePolicy(ComponentTypeEnum componentType, String componentId, String policyId, String userId, boolean shouldLock) {
132 Either<PolicyDefinition, ResponseFormat> result = null;
133 log.trace("#deletePolicy - starting to update the policy {} on the component {}. ", policyId, componentId);
134 Wrapper<Component> component = new Wrapper<>();
136 result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock)
139 component.setInnerElement(c);
140 return deletePolicy(c, policyId);
142 } catch (Exception e) {
143 log.error("#deletePolicy - the exception occurred upon update of a policy of the type {} for the component {}: ", policyId, componentId, e);
145 unlockComponent(shouldLock, result, component);
150 public Either<PolicyDefinition, ResponseFormat> updatePolicyTargets(ComponentTypeEnum componentTypeEnum, String componentId, String policyId, Map<PolicyTargetType, List<String>> targets, String userId) {
152 Either<PolicyDefinition, ResponseFormat> result = null;
153 log.debug("updating the policy id {} targets with the components {}. ", policyId, componentId);
155 //not right error response
156 result = validateAndLockComponentAndUserBeforeWriteOperation(componentTypeEnum, componentId, userId, true)
158 .bind(cmpt -> validateAndUpdatePolicyTargets(cmpt, policyId, targets));
163 unlockComponentById(result, componentId);
169 private Either<PolicyDefinition, ResponseFormat> validateAndUpdatePolicyTargets(Component component, String policyId, Map<PolicyTargetType, List<String>> targets) {
170 return validateTargetsExistAndTypesCorrect(component.getUniqueId(), targets)
172 .bind(cmp ->updateTargets(component.getUniqueId(), component.getPolicyById(policyId), targets, policyId));
176 private Either<Component, ResponseFormat> validateTargetsExistAndTypesCorrect(String componentId, Map<PolicyTargetType, List<String>> targets) {
177 Either<Component, StorageOperationStatus> componentEither = toscaOperationFacade.getToscaFullElement(componentId);
178 if (componentEither.isRight()) {
179 return Either.right(componentsUtils.getResponseFormat(componentEither.right().value()));
181 Component parentComponent = componentEither.left().value();
182 return validateTargetExists(parentComponent, targets.entrySet());
187 private Either<Component, ResponseFormat> validateTargetExists(Component parentComponent, Set<Map.Entry<PolicyTargetType, List<String>>> entries) {
188 for(Map.Entry<PolicyTargetType, List<String>> entry : entries){
189 Either<Component, ResponseFormat> result = checkTargetNotExistOnComponentByType(parentComponent, entry);
190 if(result.isRight()){
194 return Either.left(parentComponent);
197 private Either<Component, ResponseFormat> checkTargetNotExistOnComponentByType(Component parentComponent, Map.Entry<PolicyTargetType, List<String>> targetEntry) {
199 for(String id : targetEntry.getValue()){
200 if(checkNotPresenceInComponentByType(parentComponent, id, targetEntry.getKey().getName())){
201 return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_TARGET_DOES_NOT_EXIST, id));
204 return Either.left(parentComponent);
207 private boolean checkNotPresenceInComponentByType(Component parentComponent, String uniqueId, String type) {
208 if (type.equalsIgnoreCase(PolicyTargetType.GROUPS.getName()) && parentComponent.getGroups() != null) {
209 return !parentComponent.getGroupById(uniqueId).isPresent();
210 } else if (type.equalsIgnoreCase(PolicyTargetType.COMPONENT_INSTANCES.getName()) && parentComponent.getComponentInstances() != null) {
211 return !parentComponent.getComponentInstanceById(uniqueId).isPresent();
216 private PolicyDefinition setPolicyTargets(PolicyDefinition policyDefinition, Map<PolicyTargetType, List<String>> targets) {
217 policyDefinition.setTargets(targets);
218 return policyDefinition;
223 * @param componentType the type of the component
224 * @param componentId the id of the component which the policy resides under
225 * @param policyId the id of the policy which its properties to return
226 * @param userId the user id
227 * @return a list of policy properties or an error in a response format
229 public Either<List<PropertyDataDefinition>, ResponseFormat> getPolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId, String userId) {
230 log.debug("#getPolicyProperties - fetching policy properties for component {} and policy {}", componentId, policyId);
232 return validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
234 .bind(cmpt -> getPolicyById(cmpt, policyId)).left().map(PolicyDataDefinition::getProperties);
241 * Updates the policy properties of the component
243 * @param componentType the type of the component
244 * @param componentId the id of the component which the policy resides under
245 * @param policyId the id of the policy which its properties to return
246 * @param properties a list of policy properties containing updated values
247 * @param userId the user modifier id
248 * @param shouldLock the flag defining if the component should be locked
249 * @return a list of policy properties or anerrorin a response format
251 public Either<List<PropertyDataDefinition>, ResponseFormat> updatePolicyProperties(ComponentTypeEnum componentType, String componentId, String policyId, PropertyDataDefinition[] properties, String userId, boolean shouldLock) {
252 Either<List<PropertyDataDefinition>, ResponseFormat> result = null;
253 log.trace("#updatePolicyProperties - starting to update properties of the policy {} on the component {}. ", policyId, componentId);
254 Wrapper<Component> component = new Wrapper<>();
256 result = validateAndLockComponentAndUserBeforeWriteOperation(componentType, componentId, userId, shouldLock).left()
257 .bind(c -> setComponentValidateUpdatePolicyProperties(policyId, properties, component, c));
258 } catch (Exception e) {
259 log.error("#updatePolicyProperties - the exception {} occurred upon update properties of the policy {} for the component {}: ", policyId, componentId, e);
260 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
262 if (shouldLock && !component.isEmpty()) {
263 unlockComponent(result, component.getInnerElement());
269 private Either<List<PropertyDataDefinition>, ResponseFormat> setComponentValidateUpdatePolicyProperties(String policyId, PropertyDataDefinition[] properties, Wrapper<Component> component, Component c) {
270 component.setInnerElement(c);
271 Set<String> updatedPropertyNames = Arrays.stream(properties).map(PropertyDataDefinition::getName).collect(Collectors.toSet());
272 return validateAndUpdatePolicyProperties(c, policyId, properties)
274 .map(policyDefinition -> getFilteredProperties(policyDefinition.getProperties(), updatedPropertyNames));
277 private List<PropertyDataDefinition> getFilteredProperties(List<PropertyDataDefinition> all, Set<String> filtered) {
278 return all.stream().filter(pd -> filtered.contains(pd.getName())).collect(Collectors.toList());
281 private void unlockComponent(boolean shouldLock, Either<PolicyDefinition, ResponseFormat> result, Wrapper<Component> component) {
282 if (shouldLock && !component.isEmpty()) {
283 unlockComponent(result, component.getInnerElement());
287 private Either<PolicyDefinition, ResponseFormat> getPolicyById(Component component, String policyId) {
288 PolicyDefinition policyById = component.getPolicyById(policyId);
289 if (policyById == null) {
290 String cmptId = component.getUniqueId();
291 log.debug("#getPolicyById - policy with id {} does not exist on component with id {}", policyId, cmptId);
292 return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, cmptId));
294 return Either.left(policyById);
297 private Either<PolicyDefinition, ResponseFormat> createPolicy(String policyTypeName, Component component) {
298 return validatePolicyTypeOnCreatePolicy(policyTypeName, component).left().bind(type -> addPolicyToComponent(type, component));
301 private Either<PolicyDefinition, ResponseFormat> addPolicyToComponent(PolicyTypeDefinition policyType, Component component) {
302 return toscaOperationFacade.associatePolicyToComponent(component.getUniqueId(), new PolicyDefinition(policyType), getNextPolicyCounter(component.getPolicies()))
303 .either(Either::left, r -> Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(r))));
306 private Either<PolicyTypeDefinition, ResponseFormat> validatePolicyTypeOnCreatePolicy(String policyTypeName, Component component) {
307 return policyTypeOperation.getLatestPolicyTypeByType(policyTypeName)
308 .either(l -> validatePolicyTypeNotExcluded(l, component), r -> Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(r))));
311 private Either<PolicyTypeDefinition, ResponseFormat> validatePolicyTypeNotExcluded(PolicyTypeDefinition policyType, Component component) {
312 if (getExcludedPolicyTypesByComponent(component).contains(policyType.getType())) {
313 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCLUDED_POLICY_TYPE, policyType.getType(), getComponentOrResourceTypeName(component)));
315 return Either.left(policyType);
318 private String getComponentOrResourceTypeName(Component component) {
319 return component.getComponentType() == ComponentTypeEnum.SERVICE ? ComponentTypeEnum.SERVICE.name() : ((Resource) component).getResourceType().name();
322 private Either<Component, ResponseFormat> validateAndLockComponentAndUserBeforeWriteOperation(ComponentTypeEnum componentType, String componentId, String userId, boolean shouldLock) {
323 Wrapper<Component> component = new Wrapper<>();
324 return validateContainerComponentAndUserBeforeReadOperation(componentType, componentId, userId)
326 .bind(this::validateComponentIsTopologyTemplate)
329 component.setInnerElement(c);
330 return validateCanWorkOnComponent(c, userId);
333 .bind(l -> lockComponent(component.getInnerElement(), shouldLock, "policyWritingOperation"))
334 .either(l -> Either.left(component.getInnerElement()), r -> {
335 log.error(FAILED_TO_VALIDATE_COMPONENT, componentId);
336 return Either.right(r);
340 private Either<Component, ResponseFormat> validateComponentIsTopologyTemplate(Component component) {
341 if (!component.isTopologyTemplate()) {
342 log.error("#validateComponentIsTopologyTemplate - policy association to a component of Tosca type {} is not allowed. ", component.getToscaType());
343 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CANNOT_CONTAIN_POLICIES, "#validateAndLockComponentAndUserBeforeWriteOperation", component.getUniqueId(), component.getToscaType()));
345 return Either.left(component);
348 private Either<Component, ResponseFormat> validateContainerComponentAndUserBeforeReadOperation(ComponentTypeEnum componentType, String componentId, String userId) {
349 Either<Component, ResponseFormat> result;
350 log.trace("#validateContainerComponentAndUserBeforeReadOperation - starting to validate the user {} before policy processing. ", userId);
351 validateUserExists(userId, "create Policy", false);
352 result = validateComponentExists(componentType, componentId);
353 if (result.isRight()) {
354 log.error(FAILED_TO_VALIDATE_COMPONENT, "#validateContainerComponentAndUserBeforeReadOperation", componentId);
359 private Either<Component, ResponseFormat> validateComponentExists(ComponentTypeEnum componentType, String componentId) {
361 ComponentParametersView filter = new ComponentParametersView(true);
362 filter.setIgnorePolicies(false);
363 filter.setIgnoreUsers(false);
364 filter.setIgnoreComponentInstances(false);
365 filter.setIgnoreGroups(false);
366 return validateComponentExists(componentId, componentType, filter);
370 private Either<PolicyDefinition, ResponseFormat> validateAndUpdatePolicy(Component component, PolicyDefinition policy) {
371 return getPolicyById(component, policy.getUniqueId())
373 .bind(np -> validateUpdatePolicyBeforeUpdate(policy, np, component.getPolicies()))
375 .bind(p -> updatePolicyOfComponent(component, p));
378 private Either<PolicyDefinition, ResponseFormat> validateAndUpdatePolicyProperties(Component component, String policyId, PropertyDataDefinition[] properties) {
379 return getPolicyById(component, policyId)
381 .bind(p -> validateUpdatePolicyPropertiesBeforeUpdate(p, properties))
382 .left().bind(l -> updatePolicyOfComponent(component.getUniqueId(), l));
385 private Either<PolicyDefinition, ResponseFormat> updatePolicyOfComponent(String componentId, PolicyDefinition policy) {
386 return toscaOperationFacade.updatePolicyOfComponent(componentId, policy)
388 .bind(r -> Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(r))));
391 private Either<PolicyDefinition, ResponseFormat> validateUpdatePolicyPropertiesBeforeUpdate(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
392 if (CollectionUtils.isEmpty(policy.getProperties())) {
393 log.error("#validateUpdatePolicyPropertiesBeforeUpdate - failed to update properites of the policy. Properties were not found on the policy. ");
394 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND));
396 return updatePropertyValues(policy, newProperties);
399 private Either<PolicyDefinition, ResponseFormat> updatePropertyValues(PolicyDefinition policy, PropertyDataDefinition[] newProperties) {
401 Map<String, PropertyDataDefinition> oldProperties = policy.getProperties().stream().collect(toMap(PropertyDataDefinition::getName, Function.identity()));
402 for (PropertyDataDefinition newProperty : newProperties) {
403 if (!oldProperties.containsKey(newProperty.getName())) {
404 log.error("#updatePropertyValues - failed to update properites of the policy {}. Properties were not found on the policy. ", policy.getName());
405 return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getName()));
407 Either<String, ResponseFormat> newPropertyValueEither = updateInputPropertyObjectValue(newProperty);
408 if (newPropertyValueEither.isRight()) {
409 return Either.right(newPropertyValueEither.right().value());
411 oldProperties.get(newProperty.getName()).setValue(newPropertyValueEither.left().value());
413 return Either.left(policy);
416 private Either<PolicyDefinition, ResponseFormat> deletePolicy(Component component, String policyId) {
417 return getPolicyById(component, policyId)
419 .bind(p -> removePolicyFromComponent(component, p));
422 private Either<PolicyDefinition, ResponseFormat> updatePolicyOfComponent(Component component, PolicyDefinition policy) {
423 Either<PolicyDefinition, StorageOperationStatus> updatePolicyRes = toscaOperationFacade.updatePolicyOfComponent(component.getUniqueId(), policy);
424 if (updatePolicyRes.isRight()) {
425 log.error("#updatePolicyOfComponent - failed to update policy {} of the component {}. The status is {}. ", policy.getUniqueId(), component.getName(), updatePolicyRes.right().value());
426 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updatePolicyRes.right().value())));
428 log.trace("#updatePolicyOfComponent - the policy with the name {} was updated. ", updatePolicyRes.left().value().getName());
429 return Either.left(updatePolicyRes.left().value());
433 private Either<PolicyDefinition, ResponseFormat> removePolicyFromComponent(Component component, PolicyDefinition policy) {
434 StorageOperationStatus updatePolicyStatus = toscaOperationFacade.removePolicyFromComponent(component.getUniqueId(), policy.getUniqueId());
435 if (updatePolicyStatus != StorageOperationStatus.OK) {
436 log.error("#removePolicyFromComponent - failed to remove policy {} from the component {}. The status is {}. ", policy.getUniqueId(), component.getName(), updatePolicyStatus);
437 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updatePolicyStatus)));
439 log.trace("#removePolicyFromComponent - the policy with the name {} was deleted. ", updatePolicyStatus);
440 return Either.left(policy);
444 private Either<PolicyDefinition, ResponseFormat> validateUpdatePolicyBeforeUpdate(PolicyDefinition recievedPolicy, PolicyDefinition oldPolicy, Map<String, PolicyDefinition> policies) {
445 return validatePolicyFields(recievedPolicy, new PolicyDefinition(oldPolicy), policies)
447 .bind(r -> Either.right(componentsUtils.getResponseFormat(r, recievedPolicy.getName())));
450 private Either<PolicyDefinition, ResponseFormat> updateTargets(String componentId, PolicyDefinition policy, Map<PolicyTargetType, List<String>> targets, String policyId) {
452 return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_NOT_FOUND_ON_CONTAINER, policyId, componentId));
454 PolicyDefinition updatedPolicy = setPolicyTargets(policy, targets);
455 return updatePolicyOfComponent(componentId, updatedPolicy);