Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / validation / PolicyUtils.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.validation;
22
23 import fj.data.Either;
24 import org.openecomp.sdc.be.config.ConfigurationManager;
25 import org.openecomp.sdc.be.dao.api.ActionStatus;
26 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
27 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
28 import org.openecomp.sdc.be.model.Component;
29 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
30 import org.openecomp.sdc.be.model.PolicyDefinition;
31 import org.openecomp.sdc.be.model.Resource;
32 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
33 import org.openecomp.sdc.common.api.Constants;
34 import org.openecomp.sdc.common.log.wrappers.Logger;
35 import org.openecomp.sdc.common.util.ValidationUtils;
36
37 import java.util.Collections;
38 import java.util.Map;
39 import java.util.Optional;
40 import java.util.Set;
41
42 import static org.apache.commons.collections.MapUtils.isEmpty;
43 import static org.apache.commons.collections.MapUtils.isNotEmpty;
44 import static org.apache.commons.lang3.StringUtils.isEmpty;
45 import static org.apache.commons.lang3.StringUtils.isNotEmpty;
46 import static org.openecomp.sdc.common.api.Constants.GROUP_POLICY_NAME_DELIMETER;
47
48 /**
49  * Provides specific functionality for policy
50  */
51 public class PolicyUtils {
52
53     private static final Logger log = Logger.getLogger(PolicyUtils.class);
54
55     private PolicyUtils() {
56         // No instances allowed
57     }
58
59     /**
60      * Calculates the next integer counter according to the found max counter existing in the provided policies map
61      *
62      * @param policies the map of the policies
63      * @return the integer counter
64      */
65     public static int getNextPolicyCounter(Map<String, PolicyDefinition> policies) {
66         int nextCounter = 0;
67         if (isNotEmpty(policies)) {
68             int nextCounterFromIds = policies.values()
69                                              .stream()
70                                              .map(p -> extractNextPolicyCounterFromUniqueId(p.getUniqueId()))
71                                              .max(Integer::compareTo)
72                                              .orElse(0);
73             int nextCounterFromNames = policies.values()
74                                                .stream()
75                                                .map(p -> extractNextPolicyCounterFromName(p.getName()))
76                                                .max(Integer::compareTo)
77                                                .orElse(0);
78             nextCounter = nextCounterFromIds > nextCounterFromNames ? nextCounterFromIds : nextCounterFromNames;
79         }
80         return nextCounter;
81     }
82
83     /**
84      * Validates policy fields on policy update. Updates mutable fields
85      *
86      * @param recievedPolicy the policy parsed from the HTTP request
87      * @param validPolicy    the copy of the existing policy found on the component
88      * @param policies       all the polices related to the component
89      * @return validated and updated policy or an error as action status
90      */
91     public static Either<PolicyDefinition, ActionStatus> validatePolicyFields(PolicyDefinition recievedPolicy, PolicyDefinition validPolicy, Map<String, PolicyDefinition> policies) {
92         validateImmutablePolicyFields(recievedPolicy, validPolicy);
93         return validateUpdateMutablePolicyFields(recievedPolicy, validPolicy, policies);
94     }
95
96     /**
97      * Retrieves the set of the excluded policy types for the specified component
98      *
99      * @return the set of the policies
100      */
101     public static Set<String> getExcludedPolicyTypesByComponent(Component component) {
102         if (isEmpty(ConfigurationManager.getConfigurationManager()
103                                         .getConfiguration()
104                                         .getExcludedPolicyTypesMapping())) {
105             return Collections.emptySet();
106         }
107         if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
108             return ConfigurationManager.getConfigurationManager()
109                                        .getConfiguration()
110                                        .getExcludedPolicyTypesMapping()
111                                        .get(component.getComponentType().name());
112         }
113         return ConfigurationManager.getConfigurationManager()
114                                    .getConfiguration()
115                                    .getExcludedPolicyTypesMapping()
116                                    .get(((Resource) component).getResourceType().getValue());
117     }
118
119     public static PolicyDefinition getDeclaredPolicyDefinition(String componentInstanceId, ComponentInstanceProperty property) {
120         PolicyDefinition policyDefinition = new PolicyDefinition(property);
121         policyDefinition.setUniqueId(UniqueIdBuilder.buildPolicyUniqueId(componentInstanceId, property.getName()));
122         policyDefinition.setInstanceUniqueId(componentInstanceId);
123
124         return policyDefinition;
125     }
126
127     private static int extractNextPolicyCounterFromUniqueId(String uniqueId) {
128         int counter = 0;
129         if (isNotEmpty(uniqueId)) {
130             counter = extractNextPolicyCounter(uniqueId, uniqueId.lastIndexOf(Constants.POLICY_UID_POSTFIX));
131         }
132         return counter;
133     }
134
135     private static int extractNextPolicyCounterFromName(String policyName) {
136         int counter = 0;
137         if (isNotEmpty(policyName)) {
138             counter = extractNextPolicyCounter(policyName, policyName.length());
139         }
140         return counter;
141     }
142
143     private static int extractNextPolicyCounter(String policyName, int endIndex) {
144         int counter = 0;
145         try {
146             int beginIndex = policyName.lastIndexOf(GROUP_POLICY_NAME_DELIMETER) + GROUP_POLICY_NAME_DELIMETER.length();
147             String counterStr = policyName.substring(beginIndex, endIndex);
148             counter = Integer.valueOf(counterStr) + 1;
149         }
150         catch (NumberFormatException | IndexOutOfBoundsException e) {
151             log.error("#extractNextPolicyCounter - An error occurred when attempting to extract counter from policy name [{}]. ", policyName, e);
152         }
153         return counter;
154     }
155
156     private static Either<PolicyDefinition, ActionStatus> validateUpdateMutablePolicyFields(PolicyDefinition recievedPolicy, PolicyDefinition validPolicy, Map<String, PolicyDefinition> policies) {
157         return validateUpdatePolicyName(recievedPolicy, validPolicy, policies);
158     }
159
160     private static void validateImmutablePolicyFields(PolicyDefinition receivedPolicy, PolicyDefinition validPolicy) {
161         logImmutableFieldUpdateWarning(receivedPolicy.getUniqueId(), validPolicy.getUniqueId(), JsonPresentationFields.UNIQUE_ID);
162         logImmutableFieldUpdateWarning(receivedPolicy.getComponentName(), validPolicy.getComponentName(), JsonPresentationFields.CI_COMPONENT_NAME);
163         logImmutableFieldUpdateWarning(receivedPolicy.getDerivedFrom(), validPolicy.getDerivedFrom(), JsonPresentationFields.DERIVED_FROM);
164         logImmutableFieldUpdateWarning(receivedPolicy.getDescription(), validPolicy.getDescription(), JsonPresentationFields.DESCRIPTION);
165         logImmutableFieldUpdateWarning(receivedPolicy.getInvariantName(), validPolicy.getInvariantName(), JsonPresentationFields.CI_INVARIANT_NAME);
166         logImmutableFieldUpdateWarning(receivedPolicy.getInvariantUUID(), validPolicy.getInvariantUUID(), JsonPresentationFields.INVARIANT_UUID);
167         logImmutableFieldUpdateWarning(receivedPolicy.getPolicyTypeName(), validPolicy.getPolicyTypeName(), JsonPresentationFields.TYPE);
168         logImmutableFieldUpdateWarning(receivedPolicy.getPolicyTypeUid(), validPolicy.getPolicyTypeUid(), JsonPresentationFields.TYPE_UNIQUE_ID);
169         logImmutableFieldUpdateWarning(receivedPolicy.getPolicyUUID(), validPolicy.getPolicyUUID(), JsonPresentationFields.UUID);
170         logImmutableFieldUpdateWarning(receivedPolicy.getVersion(), validPolicy.getVersion(), JsonPresentationFields.VERSION);
171         logImmutableFieldUpdateWarning(receivedPolicy.getIsFromCsar().toString(), validPolicy.getIsFromCsar().toString(), JsonPresentationFields.IS_FROM_CSAR);
172     }
173
174     private static boolean isUpdatedField(String oldField, String newField) {
175         boolean isUpdatedField = false;
176         if (isEmpty(oldField) && isNotEmpty(newField)) {
177             isUpdatedField = true;
178         }
179         else if (isNotEmpty(oldField) && isNotEmpty(newField) && !oldField.equals(newField)) {
180             isUpdatedField = true;
181         }
182         return isUpdatedField;
183     }
184
185     private static void logImmutableFieldUpdateWarning(String oldValue, String newValue, JsonPresentationFields field) {
186         if (isUpdatedField(oldValue, newValue)) {
187             log.warn("#logImmutableFieldUpdateWarning - Update of the field {} of a policy not allowed. The change will be ignored. The old value is {} , the new value is {}. ", field, oldValue, newValue);
188         }
189     }
190
191     private static Either<PolicyDefinition, ActionStatus> validateUpdatePolicyName(PolicyDefinition receivedPolicy, PolicyDefinition validPolicy, Map<String, PolicyDefinition> policies) {
192         Either<PolicyDefinition, ActionStatus> result = null;
193         Optional<PolicyDefinition> sameNamePolicy = Optional.empty();
194         if (isEmpty(receivedPolicy.getName()) || !ValidationUtils.POLICY_NAME_PATTERN.matcher(receivedPolicy
195                 .getName()).matches()) {
196             log.error("#validateUpdatePolicyName - Failed to validate the name {} of the policy {}. ", receivedPolicy.getName(), receivedPolicy.getUniqueId());
197             result = Either.right(ActionStatus.INVALID_POLICY_NAME);
198         }
199         if (result == null && isNotEmpty(policies)) {
200             sameNamePolicy = policies.values()
201                                      .stream()
202                                      .filter(p -> p.getName().equals(receivedPolicy.getName()))
203                                      .findFirst();
204         }
205         if (sameNamePolicy.isPresent()) {
206             log.error("#validateUpdatePolicyName - Failed to validate the name {} of the policy {}. The policy {} with the same name already exists. ", receivedPolicy
207                     .getName(), receivedPolicy.getUniqueId(), sameNamePolicy.get().getUniqueId());
208             result = Either.right(ActionStatus.POLICY_NAME_ALREADY_EXIST);
209         }
210         if (result == null) {
211             validPolicy.setName(receivedPolicy.getName());
212             result = Either.left(validPolicy);
213         }
214         return result;
215     }
216 }