2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2020 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.api.main.rest.provider;
25 import java.util.ArrayList;
26 import java.util.List;
28 import javax.ws.rs.core.Response;
30 import org.apache.commons.lang3.tuple.Pair;
31 import org.onap.policy.models.base.PfConceptKey;
32 import org.onap.policy.models.base.PfModelException;
33 import org.onap.policy.models.base.PfModelRuntimeException;
34 import org.onap.policy.models.pdp.concepts.PdpGroup;
35 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
36 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
37 import org.onap.policy.models.tosca.legacy.concepts.LegacyOperationalPolicy;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * Class to provide all kinds of legacy operational policy operations.
44 * @author Chenfei Gao (cgao@research.att.com)
46 public class LegacyOperationalPolicyProvider extends CommonModelProvider {
48 private static final Logger LOGGER = LoggerFactory.getLogger(LegacyOperationalPolicyProvider.class);
50 private static final String INVALID_POLICY_VERSION = "legacy policy version is not an integer";
51 private static final String LEGACY_MINOR_PATCH_SUFFIX = ".0.0";
52 private static final PfConceptKey LEGACY_OPERATIONAL_TYPE =
53 new PfConceptKey("onap.policies.controlloop.Operational", "1.0.0");
56 * Default constructor.
58 public LegacyOperationalPolicyProvider() throws PfModelException {
63 * Retrieves a list of operational policies matching specified ID and version.
65 * @param policyId the ID of policy
66 * @param policyVersion the version of policy
68 * @return the LegacyOperationalPolicy object
70 public LegacyOperationalPolicy fetchOperationalPolicy(String policyId, String policyVersion)
71 throws PfModelException {
73 if (policyVersion != null) {
74 validNumber(policyVersion, INVALID_POLICY_VERSION);
76 return modelsProvider.getOperationalPolicy(policyId, policyVersion);
80 * Retrieves a list of deployed operational policies in each pdp group.
82 * @param policyId the ID of the policy
84 * @return a list of deployed policies in each pdp group
86 * @throws PfModelException the PfModel parsing exception
88 public Map<Pair<String, String>, List<LegacyOperationalPolicy>> fetchDeployedOperationalPolicies(String policyId)
89 throws PfModelException {
91 return collectDeployedPolicies(
92 policyId, LEGACY_OPERATIONAL_TYPE, modelsProvider::getOperationalPolicy, List::add, new ArrayList<>(5));
96 * Creates a new operational policy.
98 * @param body the entity body of policy
100 * @return the LegacyOperationalPolicy object
102 public LegacyOperationalPolicy createOperationalPolicy(LegacyOperationalPolicy body) throws PfModelException {
104 validateOperationalPolicyVersion(body);
105 return modelsProvider.createOperationalPolicy(body);
109 * Deletes the operational policies matching specified ID and version.
111 * @param policyId the ID of policy
112 * @param policyVersion the version of policy
114 * @return the LegacyOperationalPolicy object
116 public LegacyOperationalPolicy deleteOperationalPolicy(String policyId, String policyVersion)
117 throws PfModelException {
119 validNumber(policyVersion, INVALID_POLICY_VERSION);
120 validateDeleteEligibility(policyId, policyVersion);
122 return modelsProvider.deleteOperationalPolicy(policyId, policyVersion);
126 * Validates whether specified policy can be deleted based on the rule that deployed policy cannot be deleted.
128 * @param policyId the ID of policy
129 * @param policyVersion the version of policy
131 * @throws PfModelException the PfModel parsing exception
133 private void validateDeleteEligibility(String policyId, String policyVersion) throws PfModelException {
135 List<ToscaPolicyIdentifier> policies = new ArrayList<>(5);
136 policies.add(new ToscaPolicyIdentifier(policyId, policyVersion + LEGACY_MINOR_PATCH_SUFFIX));
137 PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder().policyList(policies).build();
139 List<PdpGroup> pdpGroups = modelsProvider.getFilteredPdpGroups(pdpGroupFilter);
141 if (!pdpGroups.isEmpty()) {
142 throw new PfModelException(Response.Status.CONFLICT,
143 constructDeletePolicyViolationMessage(policyId, policyVersion, pdpGroups));
148 * Validates the specified version of the operational policy provided in the payload.
150 * @param body the operational policy payload
152 * @throws PfModelException on errors parsing PfModel
154 private void validateOperationalPolicyVersion(LegacyOperationalPolicy body) throws PfModelException {
156 validateOperationalPolicyVersionExist(body);
157 validateNoDuplicateVersionInDb(body);
161 * Validates whether the version of the operational policy is specified in the payload.
163 * @param body the operational policy payload
165 * @throws PfModelException on errors parsing PfModel
167 private void validateOperationalPolicyVersionExist(LegacyOperationalPolicy body) throws PfModelException {
169 if (body.getPolicyVersion() == null) {
170 String errMsg = "mandatory field 'policy-version' is missing in the policy: " + body.getPolicyId();
171 throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg);
176 * Validates that there is no duplicate version of the operational policy which is already stored in the database.
178 * @param body the operational policy payload
180 * @throws PfModelException on errors parsing PfModel
182 private void validateNoDuplicateVersionInDb(LegacyOperationalPolicy body) throws PfModelException {
185 modelsProvider.getOperationalPolicy(body.getPolicyId(), body.getPolicyVersion());
186 } catch (PfModelRuntimeException exc) {
187 if (!hasSameOperationalPolicyFound(body, exc)) {
190 throw new PfModelException(exc.getErrorResponse().getResponseCode(), "unexpected runtime error", exc);
193 // There is one duplicate version stored in the DB.
194 // Try to get the latest version
195 LegacyOperationalPolicy latest = modelsProvider.getOperationalPolicy(body.getPolicyId(), null);
196 final String[] versionArray = latest.getPolicyVersion().split("\\.");
197 String errMsg = "operational policy " + body.getPolicyId() + ":" + body.getPolicyVersion()
198 + " already exists; its latest version is " + versionArray[0];
199 throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errMsg);
203 * Checks if the same operational policy found in the database.
205 * @param body the legacy operational policy payload
206 * @param exc the runtime exception thrown by policy model provider
208 * @return a boolean flag indicating the check result
210 private boolean hasSameOperationalPolicyFound(LegacyOperationalPolicy body, PfModelRuntimeException exc) {
212 if (exc.getErrorResponse().getResponseCode() == Response.Status.BAD_REQUEST
213 && exc.getErrorResponse().getErrorMessage().contains("no policy found")) {
214 LOGGER.debug("no duplicate policy {}:{} found in the DB", body.getPolicyId(), body.getPolicyVersion());