99dcd715443f69fe2fa29482defdc1fb854f8410
[policy/api.git] / main / src / main / java / org / onap / policy / api / main / rest / provider / PolicyProvider.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * ONAP Policy API\r
4  * ================================================================================\r
5  * Copyright (C) 2019 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
10  *\r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  *\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
18  *\r
19  * SPDX-License-Identifier: Apache-2.0\r
20  * ============LICENSE_END=========================================================\r
21  */\r
22 \r
23 package org.onap.policy.api.main.rest.provider;\r
24 \r
25 import java.util.ArrayList;\r
26 import java.util.List;\r
27 import java.util.Map;\r
28 import javax.ws.rs.core.Response;\r
29 import org.apache.commons.lang3.tuple.Pair;\r
30 import org.onap.policy.models.base.PfConceptKey;\r
31 import org.onap.policy.models.base.PfModelException;\r
32 import org.onap.policy.models.pdp.concepts.PdpGroup;\r
33 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;\r
34 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;\r
35 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;\r
36 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;\r
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;\r
38 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;\r
39 \r
40 /**\r
41  * Class to provide all kinds of policy operations.\r
42  *\r
43  * @author Chenfei Gao (cgao@research.att.com)\r
44  */\r
45 public class PolicyProvider extends CommonModelProvider {\r
46 \r
47     /**\r
48      * Default constructor.\r
49      */\r
50     public PolicyProvider() throws PfModelException {\r
51         super();\r
52     }\r
53 \r
54     /**\r
55      * Retrieves a list of policies matching specified ID and version of both policy type and policy.\r
56      *\r
57      * @param policyTypeId the ID of policy type\r
58      * @param policyTypeVersion the version of policy type\r
59      * @param policyId the ID of policy\r
60      * @param policyVersion the version of policy\r
61      *\r
62      * @return the ToscaServiceTemplate object\r
63      *\r
64      * @throws PfModelException the PfModel parsing exception\r
65      */\r
66     public ToscaServiceTemplate fetchPolicies(String policyTypeId, String policyTypeVersion,\r
67             String policyId, String policyVersion) throws PfModelException {\r
68 \r
69         ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()\r
70                 .name(policyId).version(policyVersion)\r
71                 .type(policyTypeId).typeVersion(policyTypeVersion).build();\r
72         ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);\r
73 \r
74         if (!hasPolicy(serviceTemplate)) {\r
75             throw new PfModelException(Response.Status.NOT_FOUND,\r
76                     constructResourceNotFoundMessage(policyTypeId, policyTypeVersion, policyId, policyVersion));\r
77         }\r
78 \r
79         return serviceTemplate;\r
80     }\r
81 \r
82     /**\r
83      * Retrieves a list of policies with the latest versions that match specified policy type id and version.\r
84      *\r
85      * @param policyTypeId the ID of policy type\r
86      * @param policyTypeVersion the version of policy type\r
87      * @param policyId the ID of the policy\r
88      *\r
89      * @return the ToscaServiceTemplate object\r
90      *\r
91      * @throws PfModelException the PfModel parsing exception\r
92      */\r
93     public ToscaServiceTemplate fetchLatestPolicies(String policyTypeId, String policyTypeVersion,\r
94             String policyId) throws PfModelException {\r
95 \r
96         ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()\r
97                 .name(policyId).version(ToscaPolicyFilter.LATEST_VERSION)\r
98                 .type(policyTypeId).typeVersion(policyTypeVersion).build();\r
99         ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);\r
100 \r
101         if (!hasPolicy(serviceTemplate)) {\r
102             throw new PfModelException(Response.Status.NOT_FOUND,\r
103                     constructResourceNotFoundMessage(policyTypeId, policyTypeVersion, policyId, null));\r
104         }\r
105 \r
106         return serviceTemplate;\r
107     }\r
108 \r
109     /**\r
110      * Retrieves a list of deployed policies in each pdp group.\r
111      *\r
112      * @param policyTypeId the ID of policy type\r
113      * @param policyTypeVersion the version of policy type\r
114      * @param policyId the ID of the policy\r
115      *\r
116      * @return a list of deployed policies in each pdp group\r
117      *\r
118      * @throws PfModelException the PfModel parsing exception\r
119      */\r
120     public Map<Pair<String, String>, List<ToscaPolicy>> fetchDeployedPolicies(\r
121             String policyTypeId, String policyTypeVersion, String policyId) throws PfModelException {\r
122 \r
123         return collectDeployedPolicies(policyId, new PfConceptKey(policyTypeId, policyTypeVersion),\r
124                 modelsProvider::getPolicyList, List::addAll, new ArrayList<>());\r
125     }\r
126 \r
127     /**\r
128      * Creates a new policy for a policy type ID and version.\r
129      *\r
130      * @param policyTypeId the ID of policy type\r
131      * @param policyTypeVersion the version of policy type\r
132      * @param body the entity body of policy\r
133      *\r
134      * @return the ToscaServiceTemplate object\r
135      *\r
136      * @throws PfModelException the PfModel parsing exception\r
137      */\r
138     public ToscaServiceTemplate createPolicy(String policyTypeId, String policyTypeVersion,\r
139                                              ToscaServiceTemplate body) throws PfModelException {\r
140 \r
141         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
142         validatePolicyTypeMatch(policyTypeId, policyTypeVersion, body);\r
143 \r
144         return modelsProvider.createPolicies(body);\r
145     }\r
146 \r
147     /**\r
148      * Creates one or more new policies.\r
149      *\r
150      * @param body the entity body of policy\r
151      *\r
152      * @return the ToscaServiceTemplate object\r
153      *\r
154      * @throws PfModelException the PfModel parsing exception\r
155      */\r
156     public ToscaServiceTemplate createPolicies(ToscaServiceTemplate body) throws PfModelException {\r
157 \r
158         return modelsProvider.createPolicies(body);\r
159     }\r
160 \r
161     /**\r
162      * Deletes the policy matching specified ID and version of both policy type and policy.\r
163      *\r
164      * @param policyTypeId the ID of policy type\r
165      * @param policyTypeVersion the version of policy type\r
166      * @param policyId the ID of policy\r
167      * @param policyVersion the version of policy\r
168      *\r
169      * @return the ToscaServiceTemplate object\r
170      *\r
171      * @throws PfModelException the PfModel parsing exception\r
172      */\r
173     public ToscaServiceTemplate deletePolicy(String policyTypeId, String policyTypeVersion,\r
174                                  String policyId, String policyVersion) throws PfModelException {\r
175 \r
176         validateDeleteEligibility(policyTypeId, policyTypeVersion, policyId, policyVersion);\r
177 \r
178         ToscaServiceTemplate serviceTemplate = modelsProvider.deletePolicy(policyId, policyVersion);\r
179 \r
180         if (!hasPolicy(serviceTemplate)) {\r
181             throw new PfModelException(Response.Status.NOT_FOUND,\r
182                     constructResourceNotFoundMessage(policyTypeId, policyTypeVersion, policyId, policyVersion));\r
183         }\r
184 \r
185         return serviceTemplate;\r
186     }\r
187 \r
188     /**\r
189      * Validates whether policy type exists.\r
190      *\r
191      * @param policyTypeId the ID of policy type\r
192      * @param policyTypeVersion the version of policy type\r
193      *\r
194      * @throws PfModelException the PfModel parsing exception\r
195      */\r
196     private void validatePolicyTypeExist(String policyTypeId, String policyTypeVersion) throws PfModelException {\r
197 \r
198         ToscaServiceTemplate serviceTemplate = modelsProvider.getPolicyTypes(policyTypeId, policyTypeVersion);\r
199         if (!hasPolicyType(serviceTemplate)) {\r
200             throw new PfModelException(Response.Status.NOT_FOUND,\r
201                     "policy type with ID " + policyTypeId + ":" + policyTypeVersion + " does not exist");\r
202         }\r
203     }\r
204 \r
205     /**\r
206      * Validates the match between policy type specified in path and the one specified in type of policy.\r
207      *\r
208      * @param policyTypeId the ID of policy type\r
209      * @param policyTypeVersion the version of policy type\r
210      * @param serviceTemplate the ToscaServiceTemplate to validate\r
211      *\r
212      * @throws PfModelException the PfModel parsing exception\r
213      */\r
214     private void validatePolicyTypeMatch(String policyTypeId, String policyTypeVersion,\r
215             ToscaServiceTemplate serviceTemplate) throws PfModelException {\r
216 \r
217         List<Map<String, ToscaPolicy>> policies = serviceTemplate.getToscaTopologyTemplate().getPolicies();\r
218         for (Map<String, ToscaPolicy> policy : policies) {\r
219             if (policy.size() > 1) {\r
220                 throw new PfModelException(Response.Status.BAD_REQUEST,\r
221                         "one policy block contains more than one policies");\r
222             }\r
223             ToscaPolicy policyContent = policy.values().iterator().next();\r
224             if (!policyTypeId.equalsIgnoreCase(policyContent.getType())) {\r
225                 throw new PfModelException(Response.Status.BAD_REQUEST, "policy type id does not match");\r
226             }\r
227             if (policyContent.getTypeVersion() != null\r
228                     && !policyTypeVersion.equalsIgnoreCase(policyContent.getTypeVersion())) {\r
229                 throw new PfModelException(Response.Status.BAD_REQUEST, "policy type version does not match");\r
230             }\r
231         }\r
232     }\r
233 \r
234     /**\r
235      * Validates whether specified policy can be deleted based on the rule that deployed policy cannot be deleted.\r
236      *\r
237      * @param policyTypeId the ID of policy type\r
238      * @param policyTypeVersion the version of policy type\r
239      * @param policyId the ID of policy\r
240      * @param policyVersion the version of policy\r
241      *\r
242      * @throws PfModelException the PfModel parsing exception\r
243      */\r
244     private void validateDeleteEligibility(String policyTypeId, String policyTypeVersion,\r
245             String policyId, String policyVersion) throws PfModelException {\r
246 \r
247         List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>();\r
248         policyTypes.add(new ToscaPolicyTypeIdentifier(policyTypeId, policyTypeVersion));\r
249         List<ToscaPolicyIdentifier> policies = new ArrayList<>();\r
250         policies.add(new ToscaPolicyIdentifier(policyId, policyVersion));\r
251         PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder()\r
252                 .policyTypeList(policyTypes).policyList(policies).build();\r
253 \r
254         List<PdpGroup> pdpGroups = modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
255 \r
256         if (!pdpGroups.isEmpty()) {\r
257             throw new PfModelException(Response.Status.CONFLICT,\r
258                     constructDeletePolicyViolationMessage(policyId, policyVersion, pdpGroups));\r
259         }\r
260     }\r
261 \r
262     /**\r
263      * Constructs returned message for not found resource.\r
264      *\r
265      * @param policyTypeId the ID of policy type\r
266      * @param policyTypeVersion the version of policy type\r
267      * @param policyId the ID of policy\r
268      * @param policyVersion the version of policy\r
269      *\r
270      * @return constructed message\r
271      */\r
272     private String constructResourceNotFoundMessage(String policyTypeId, String policyTypeVersion,\r
273             String policyId, String policyVersion) {\r
274 \r
275         return "policy with ID " + policyId + ":" + policyVersion\r
276                 + " and type " + policyTypeId + ":" + policyTypeVersion + " does not exist";\r
277     }\r
278 }\r