Incorporate filters in provider functions
[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.List;\r
26 import java.util.Map;\r
27 import javax.ws.rs.core.Response;\r
28 import org.apache.commons.lang3.tuple.Pair;\r
29 import org.onap.policy.api.main.parameters.ApiParameterGroup;\r
30 import org.onap.policy.common.parameters.ParameterService;\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.provider.PolicyModelsProvider;\r
35 import org.onap.policy.models.provider.PolicyModelsProviderFactory;\r
36 import org.onap.policy.models.provider.PolicyModelsProviderParameters;\r
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;\r
38 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;\r
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;\r
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;\r
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;\r
42 \r
43 /**\r
44  * Class to provide all kinds of policy operations.\r
45  *\r
46  * @author Chenfei Gao (cgao@research.att.com)\r
47  */\r
48 public class PolicyProvider {\r
49 \r
50     private PolicyModelsProvider modelsProvider;\r
51 \r
52     /**\r
53      * Default constructor.\r
54      */\r
55     public PolicyProvider() throws PfModelException {\r
56 \r
57         ApiParameterGroup parameterGroup = ParameterService.get("ApiGroup");\r
58         PolicyModelsProviderParameters providerParameters = parameterGroup.getDatabaseProviderParameters();\r
59         modelsProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(providerParameters);\r
60     }\r
61 \r
62     /**\r
63      * Retrieves a list of policies matching specified ID and version of both policy type and policy.\r
64      *\r
65      * @param policyTypeId the ID of policy type\r
66      * @param policyTypeVersion the version of policy type\r
67      * @param policyId the ID of policy\r
68      * @param policyVersion the version of policy\r
69      *\r
70      * @return the ToscaServiceTemplate object\r
71      *\r
72      * @throws PfModelException the PfModel parsing exception\r
73      */\r
74     public ToscaServiceTemplate fetchPolicies(String policyTypeId, String policyTypeVersion,\r
75             String policyId, String policyVersion) throws PfModelException {\r
76 \r
77         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
78 \r
79         ToscaServiceTemplate serviceTemplate;\r
80         if (policyId == null || policyVersion == null) {\r
81             ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()\r
82                     .name(policyId).version(policyVersion)\r
83                     .type(policyTypeId).typeVersion(policyTypeVersion).build();\r
84             serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);\r
85         } else {\r
86             serviceTemplate = modelsProvider.getPolicies(policyId, policyVersion);\r
87         }\r
88 \r
89         validatePolicyTypeMatch(policyTypeId, policyTypeVersion, serviceTemplate);\r
90 \r
91         close();\r
92         return serviceTemplate;\r
93     }\r
94 \r
95     /**\r
96      * Retrieves a list of policies with the latest versions that match specified policy type id and version.\r
97      *\r
98      * @param policyTypeId the ID of policy type\r
99      * @param policyTypeVersion the version of policy type\r
100      * @param policyId the ID of the policy\r
101      *\r
102      * @return the ToscaServiceTemplate object\r
103      *\r
104      * @throws PfModelException the PfModel parsing exception\r
105      */\r
106     public ToscaServiceTemplate fetchLatestPolicies(String policyTypeId, String policyTypeVersion,\r
107             String policyId) throws PfModelException {\r
108 \r
109         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
110 \r
111         ToscaPolicyFilter policyFilter = ToscaPolicyFilter.builder()\r
112                 .name(policyId).version(ToscaPolicyFilter.LATEST_VERSION)\r
113                 .type(policyTypeId).typeVersion(policyTypeVersion).build();\r
114         ToscaServiceTemplate serviceTemplate = modelsProvider.getFilteredPolicies(policyFilter);\r
115 \r
116         validatePolicyTypeMatch(policyTypeId, policyTypeVersion, serviceTemplate);\r
117 \r
118         close();\r
119         return serviceTemplate;\r
120     }\r
121 \r
122     /**\r
123      * Retrieves a list of deployed policies in each pdp group.\r
124      *\r
125      * @param policyTypeId the ID of policy type\r
126      * @param policyTypeVersion the version of policy type\r
127      * @param policyId the ID of the policy\r
128      *\r
129      * @return a list of deployed policies in each pdp group\r
130      *\r
131      * @throws PfModelException the PfModel parsing exception\r
132      */\r
133     public Map<Pair<String, String>, List<ToscaPolicy>> fetchDeployedPolicies(\r
134             String policyTypeId, String policyTypeVersion, String policyId) throws PfModelException {\r
135 \r
136         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
137 \r
138         ToscaPolicyIdentifier policyIdentifier = new ToscaPolicyIdentifier();\r
139         policyIdentifier.setName(policyId);\r
140         PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder()\r
141                 .policyType(new ToscaPolicyTypeIdentifier(policyTypeId, policyTypeVersion))\r
142                 .policy(policyIdentifier).build();\r
143         List<PdpGroup> pdpGroups = modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
144 \r
145         //TODO: I don't know how to get policies matching policyId that are deployed in those PDP groups\r
146 \r
147         close();\r
148         return null;\r
149     }\r
150 \r
151     /**\r
152      * Creates a new policy for a policy type ID and version.\r
153      *\r
154      * @param policyTypeId the ID of policy type\r
155      * @param policyTypeVersion the version of policy type\r
156      * @param body the entity body of policy\r
157      *\r
158      * @return the ToscaServiceTemplate object\r
159      *\r
160      * @throws PfModelException the PfModel parsing exception\r
161      */\r
162     public ToscaServiceTemplate createPolicy(String policyTypeId, String policyTypeVersion,\r
163                                              ToscaServiceTemplate body) throws PfModelException {\r
164 \r
165         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
166         validatePolicyTypeMatch(policyTypeId, policyTypeVersion, body);\r
167 \r
168         ToscaServiceTemplate serviceTemplate = modelsProvider.createPolicies(body);\r
169 \r
170         close();\r
171         return serviceTemplate;\r
172     }\r
173 \r
174     /**\r
175      * Deletes the policy matching specified ID and version of both policy type and policy.\r
176      *\r
177      * @param policyTypeId the ID of policy type\r
178      * @param policyTypeVersion the version of policy type\r
179      * @param policyId the ID of policy\r
180      * @param policyVersion the version of policy\r
181      *\r
182      * @return the ToscaServiceTemplate object\r
183      *\r
184      * @throws PfModelException the PfModel parsing exception\r
185      */\r
186     public ToscaServiceTemplate deletePolicy(String policyTypeId, String policyTypeVersion,\r
187                                  String policyId, String policyVersion) throws PfModelException {\r
188 \r
189         validatePolicyTypeExist(policyTypeId, policyTypeVersion);\r
190 \r
191         ToscaServiceTemplate serviceTemplate = modelsProvider.getPolicies(policyId, policyVersion);\r
192 \r
193         validatePolicyTypeMatch(policyTypeId, policyTypeVersion, serviceTemplate);\r
194         validateDeleteEligibility(policyTypeId, policyTypeVersion, policyId, policyVersion);\r
195 \r
196         ToscaServiceTemplate deletedServiceTemplate = modelsProvider.deletePolicy(policyId, policyVersion);\r
197 \r
198         close();\r
199         return deletedServiceTemplate;\r
200     }\r
201 \r
202     /**\r
203      * Validates whether policy type exists.\r
204      *\r
205      * @param policyTypeId the ID of policy type\r
206      * @param policyTypeVersion the version of policy type\r
207      *\r
208      * @throws PfModelException the PfModel parsing exception\r
209      */\r
210     private void validatePolicyTypeExist(String policyTypeId, String policyTypeVersion) throws PfModelException {\r
211 \r
212         try {\r
213             modelsProvider.getPolicyTypes(policyTypeId, policyTypeVersion);\r
214         } catch (Exception e) {\r
215             throw new PfModelException(Response.Status.NOT_FOUND, "specified policy type does not exist", e);\r
216         }\r
217     }\r
218 \r
219     /**\r
220      * Validates the match between policy type specified in path and the one specified in type of policy.\r
221      *\r
222      * @param policyTypeId the ID of policy type\r
223      * @param policyTypeVersion the version of policy type\r
224      * @param serviceTemplate the ToscaServiceTemplate to validate\r
225      *\r
226      * @throws PfModelException the PfModel parsing exception\r
227      */\r
228     private void validatePolicyTypeMatch(String policyTypeId, String policyTypeVersion,\r
229             ToscaServiceTemplate serviceTemplate) throws PfModelException {\r
230 \r
231         List<Map<String, ToscaPolicy>> policies = serviceTemplate.getToscaTopologyTemplate().getPolicies();\r
232         for (Map<String, ToscaPolicy> policy : policies) {\r
233             if (policy.size() != 1) {\r
234                 throw new PfModelException(Response.Status.BAD_REQUEST,\r
235                         "one policy block contains more than one policies");\r
236             }\r
237             ToscaPolicy policyContent = policy.values().iterator().next();\r
238             if (!policyTypeId.equalsIgnoreCase(policyContent.getType())\r
239                     || !policyTypeVersion.equalsIgnoreCase(policyContent.getTypeVersion())) {\r
240                 throw new PfModelException(Response.Status.BAD_REQUEST, "policy type does not match");\r
241             }\r
242         }\r
243     }\r
244 \r
245     /**\r
246      * Validates whether specified policy can be deleted based on the rule that deployed policy cannot be deleted.\r
247      *\r
248      * @param policyTypeId the ID of policy type\r
249      * @param policyTypeVersion the version of policy type\r
250      * @param policyId the ID of policy\r
251      * @param policyVersion the version of policy\r
252      *\r
253      * @throws PfModelException the PfModel parsing exception\r
254      */\r
255     private void validateDeleteEligibility(String policyTypeId, String policyTypeVersion,\r
256             String policyId, String policyVersion) throws PfModelException {\r
257 \r
258         PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder()\r
259                 .policyType(new ToscaPolicyTypeIdentifier(policyTypeId, policyTypeVersion))\r
260                 .policy(new ToscaPolicyIdentifier(policyId, policyVersion)).build();\r
261 \r
262         List<PdpGroup> pdpGroups = modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
263         if (!pdpGroups.isEmpty()) {\r
264             throw new PfModelException(Response.Status.CONFLICT, "the policy has been deployed in pdp group");\r
265         }\r
266     }\r
267 \r
268     /**\r
269      * Closes the connection to database.\r
270      *\r
271      * @throws PfModelException the PfModel parsing exception\r
272      */\r
273     private void close() throws PfModelException {\r
274         try {\r
275             modelsProvider.close();\r
276         } catch (Exception e) {\r
277             throw new PfModelException(\r
278                     Response.Status.INTERNAL_SERVER_ERROR, "error closing connection to database", e);\r
279         }\r
280     }\r
281 }\r