2 * ============LICENSE_START=======================================================
\r
4 * ================================================================================
\r
5 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
\r
6 * ================================================================================
\r
7 * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * you may not use this file except in compliance with the License.
\r
9 * You may obtain a copy of the License at
\r
11 * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * Unless required by applicable law or agreed to in writing, software
\r
14 * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * See the License for the specific language governing permissions and
\r
17 * limitations under the License.
\r
19 * SPDX-License-Identifier: Apache-2.0
\r
20 * ============LICENSE_END=========================================================
\r
23 package org.onap.policy.api.main.rest.provider;
\r
25 import java.util.ArrayList;
\r
26 import java.util.HashMap;
\r
27 import java.util.List;
\r
28 import java.util.Map;
\r
29 import java.util.Map.Entry;
\r
30 import javax.ws.rs.core.Response;
\r
32 import org.onap.policy.models.base.PfModelException;
\r
33 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
\r
34 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
\r
35 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
\r
36 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeFilter;
\r
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
\r
40 * Class to provide all kinds of policy type operations.
\r
42 * @author Chenfei Gao (cgao@research.att.com)
\r
44 public class PolicyTypeProvider extends CommonModelProvider {
\r
47 * Default constructor.
\r
49 public PolicyTypeProvider() throws PfModelException {
\r
54 * Retrieves a list of policy types matching specified policy type ID and version.
\r
56 * @param policyTypeId the ID of policy type
\r
57 * @param policyTypeVersion the version of policy type
\r
59 * @return the ToscaServiceTemplate object
\r
61 * @throws PfModelException the PfModel parsing exception
\r
63 public ToscaServiceTemplate fetchPolicyTypes(String policyTypeId, String policyTypeVersion)
\r
64 throws PfModelException {
\r
66 ToscaServiceTemplate serviceTemplate = getFilteredPolicyTypes(policyTypeId, policyTypeVersion);
\r
68 if (policyTypeId != null && !hasPolicyType(serviceTemplate)) {
\r
69 throw new PfModelException(Response.Status.NOT_FOUND,
\r
70 constructResourceNotFoundMessage(policyTypeId, policyTypeVersion));
\r
73 return serviceTemplate;
\r
77 * Retrieves a list of policy types with the latest versions.
\r
79 * @param policyTypeId the ID of policy type
\r
81 * @return the ToscaServiceTemplate object
\r
83 * @throws PfModelException the PfModel parsing exception
\r
85 public ToscaServiceTemplate fetchLatestPolicyTypes(String policyTypeId) throws PfModelException {
\r
87 ToscaServiceTemplate serviceTemplate =
\r
88 getFilteredPolicyTypes(policyTypeId, ToscaPolicyTypeFilter.LATEST_VERSION);
\r
89 if (!hasPolicyType(serviceTemplate)) {
\r
90 throw new PfModelException(Response.Status.NOT_FOUND,
\r
91 constructResourceNotFoundMessage(policyTypeId, null));
\r
94 return serviceTemplate;
\r
98 * Creates a new policy type.
\r
100 * @param body the entity body of policy type
\r
102 * @return the ToscaServiceTemplate object
\r
103 * @throws PfModelException the PfModel parsing exception
\r
105 public ToscaServiceTemplate createPolicyType(ToscaServiceTemplate body) throws PfModelException {
\r
107 if (!hasPolicyType(body)) {
\r
108 throw new PfModelException(Response.Status.BAD_REQUEST,
\r
109 "no policy types specified in the service template");
\r
111 validatePolicyTypeVersion(body);
\r
112 return modelsProvider.createPolicyTypes(body);
\r
116 * Delete the policy type matching specified policy type ID and version.
\r
118 * @param policyTypeId the ID of policy type
\r
119 * @param policyTypeVersion the version of policy type
\r
121 * @return the ToscaServiceTemplate object
\r
123 * @throws PfModelException the PfModel parsing exception
\r
125 public ToscaServiceTemplate deletePolicyType(String policyTypeId, String policyTypeVersion)
\r
126 throws PfModelException {
\r
128 validateDeleteEligibility(policyTypeId, policyTypeVersion);
\r
130 ToscaServiceTemplate serviceTemplate = modelsProvider.deletePolicyType(policyTypeId, policyTypeVersion);
\r
132 if (!hasPolicyType(serviceTemplate)) {
\r
133 throw new PfModelException(Response.Status.NOT_FOUND,
\r
134 constructResourceNotFoundMessage(policyTypeId, policyTypeVersion));
\r
137 return serviceTemplate;
\r
141 * Validates whether specified policy type can be deleted based on the rule that
\r
142 * policy type parameterized by at least one policies cannot be deleted.
\r
144 * @param policyTypeId the ID of policy type
\r
145 * @param policyTypeVersion the version of policy type
\r
147 * @throws PfModelException the PfModel parsing exception
\r
149 private void validateDeleteEligibility(String policyTypeId, String policyTypeVersion) throws PfModelException {
\r
151 ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()
\r
152 .type(policyTypeId).typeVersion(policyTypeVersion).build();
\r
153 List<ToscaPolicy> policies = modelsProvider.getFilteredPolicyList(policyFilter);
\r
154 if (!policies.isEmpty()) {
\r
155 throw new PfModelException(Response.Status.CONFLICT,
\r
156 constructDeletePolicyTypeViolationMessage(policyTypeId, policyTypeVersion, policies));
\r
161 * Validates the provided policy type version in the payload.
\r
163 * @param body the provided TOSCA service template which contains the policy types
\r
165 * @throws PfModelException the PfModel parsing exception
\r
167 private void validatePolicyTypeVersion(ToscaServiceTemplate body) throws PfModelException {
\r
169 validatePolicyTypeVersionExist(body);
\r
170 validateNoDuplicateVersionInDb(body);
\r
174 * Validates that each policy type has a version specified in the payload.
\r
176 * @param body the TOSCA service template payload to check against
\r
178 * @throws PfModelException the PfModel parsing exception
\r
180 private void validatePolicyTypeVersionExist(ToscaServiceTemplate body) throws PfModelException {
\r
182 List<String> invalidPolicyTypeNames = new ArrayList<>();
\r
183 for (Entry<String, ToscaPolicyType> policyType: body.getPolicyTypes().entrySet()) {
\r
184 if (!"tosca.policies.Root".equals(policyType.getValue().getDerivedFrom())
\r
185 && policyType.getValue().getVersion() == null) {
\r
186 invalidPolicyTypeNames.add(policyType.getKey());
\r
190 if (!invalidPolicyTypeNames.isEmpty()) {
\r
191 String errorMsg = "mandatory 'version' field is missing in policy types: "
\r
192 + String.join(", ", invalidPolicyTypeNames);
\r
193 throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errorMsg);
\r
198 * Validates that there is no duplicate version of the policy type stored in the database.
\r
200 * @param body the TOSCA service template payload
\r
202 * @throws PfModelException the PfModel parsing exception
\r
204 private void validateNoDuplicateVersionInDb(ToscaServiceTemplate body) throws PfModelException {
\r
206 Map<String, String> invalidPolicyTypes = new HashMap<>();
\r
207 for (Entry<String, ToscaPolicyType> policyType: body.getPolicyTypes().entrySet()) {
\r
208 if ("tosca.policies.Root".equals(policyType.getValue().getDerivedFrom())) {
\r
211 String policyTypeName = policyType.getKey();
\r
212 String policyTypeVersion = policyType.getValue().getVersion();
\r
213 ToscaServiceTemplate serviceTemplate = getFilteredPolicyTypes(policyTypeName, policyTypeVersion);
\r
214 if (hasPolicyType(serviceTemplate)) {
\r
215 String latestVersion = getFilteredPolicyTypes(policyTypeName, ToscaPolicyTypeFilter.LATEST_VERSION)
\r
216 .getPolicyTypesAsMap().entrySet().iterator().next().getKey().getVersion();
\r
217 invalidPolicyTypes.put(String.join(":", policyTypeName, policyTypeVersion), latestVersion);
\r
221 if (!invalidPolicyTypes.isEmpty()) {
\r
222 List<String> duplicateVersions = new ArrayList<>(invalidPolicyTypes.size());
\r
223 for (Entry<String, String> invalidPolicyType : invalidPolicyTypes.entrySet()) {
\r
224 String eachDuplicateVersion = "policy type " + invalidPolicyType.getKey()
\r
225 + " already exists; its latest version is " + invalidPolicyType.getValue();
\r
226 duplicateVersions.add(eachDuplicateVersion);
\r
228 throw new PfModelException(Response.Status.NOT_ACCEPTABLE, String.join("\n", duplicateVersions));
\r
233 * Retrieves the specified version of the policy type.
\r
235 * @param policyTypeName the name of the policy type
\r
236 * @param policyTypeVersion the version of the policy type
\r
238 * @return the TOSCA service template containing the specified version of the policy type
\r
240 * @throws PfModelException the PfModel parsing exception
\r
242 private ToscaServiceTemplate getFilteredPolicyTypes(String policyTypeName, String policyTypeVersion)
\r
243 throws PfModelException {
\r
245 ToscaPolicyTypeFilter policyTypeFilter = ToscaPolicyTypeFilter.builder()
\r
246 .name(policyTypeName).version(policyTypeVersion).build();
\r
247 return modelsProvider.getFilteredPolicyTypes(policyTypeFilter);
\r
251 * Constructs returned message for not found resource.
\r
253 * @param policyTypeId the ID of policy type
\r
254 * @param policyTypeVersion the version of policy type
\r
256 * @return constructed message
\r
258 private String constructResourceNotFoundMessage(String policyTypeId, String policyTypeVersion) {
\r
260 return "policy type with ID " + policyTypeId + ":" + policyTypeVersion + " does not exist";
\r