db864d7ab888836b60bd51f147ab1d48cbce5808
[policy/api.git] / main / src / main / java / org / onap / policy / api / main / rest / provider / CommonModelProvider.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * ONAP Policy API\r
4  * ================================================================================\r
5  * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.\r
6  * Modifications Copyright (C) 2019-2020 Nordix Foundation.\r
7  * ================================================================================\r
8  * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * you may not use this file except in compliance with the License.\r
10  * You may obtain a copy of the License at\r
11  *\r
12  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  *\r
14  * Unless required by applicable law or agreed to in writing, software\r
15  * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * See the License for the specific language governing permissions and\r
18  * limitations under the License.\r
19  *\r
20  * SPDX-License-Identifier: Apache-2.0\r
21  * ============LICENSE_END=========================================================\r
22  */\r
23 \r
24 package org.onap.policy.api.main.rest.provider;\r
25 \r
26 import java.util.ArrayList;\r
27 import java.util.HashMap;\r
28 import java.util.List;\r
29 import java.util.Map;\r
30 import java.util.function.BiConsumer;\r
31 \r
32 import javax.ws.rs.core.Response;\r
33 \r
34 import org.apache.commons.lang3.tuple.Pair;\r
35 import org.onap.policy.api.main.parameters.ApiParameterGroup;\r
36 import org.onap.policy.common.parameters.ParameterService;\r
37 import org.onap.policy.models.base.PfConceptKey;\r
38 import org.onap.policy.models.base.PfModelException;\r
39 import org.onap.policy.models.pdp.concepts.PdpGroup;\r
40 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;\r
41 import org.onap.policy.models.pdp.concepts.PdpSubGroup;\r
42 import org.onap.policy.models.pdp.enums.PdpState;\r
43 import org.onap.policy.models.provider.PolicyModelsProvider;\r
44 import org.onap.policy.models.provider.PolicyModelsProviderFactory;\r
45 import org.onap.policy.models.provider.PolicyModelsProviderParameters;\r
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;\r
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;\r
48 \r
49 /**\r
50  * Super class for providers that use a model provider.\r
51  */\r
52 public class CommonModelProvider implements AutoCloseable {\r
53 \r
54     protected final PolicyModelsProvider modelsProvider;\r
55 \r
56     /**\r
57      * Constructs the object, populating {@link #modelsProvider}.\r
58      *\r
59      * @throws PfModelException if an error occurs\r
60      */\r
61     public CommonModelProvider() throws PfModelException {\r
62 \r
63         ApiParameterGroup parameterGroup = ParameterService.get("ApiGroup");\r
64         PolicyModelsProviderParameters providerParameters = parameterGroup.getDatabaseProviderParameters();\r
65         modelsProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(providerParameters);\r
66     }\r
67 \r
68     /**\r
69      * Closes the connection to database.\r
70      *\r
71      * @throws PfModelException the PfModel parsing exception\r
72      */\r
73     @Override\r
74     public void close() throws PfModelException {\r
75 \r
76         modelsProvider.close();\r
77     }\r
78 \r
79     /**\r
80      * Collects all deployed versions of specified policy in all pdp groups.\r
81      *\r
82      * @param policyId the ID of policy\r
83      * @param policyType the concept key of policy type\r
84      * @param getter the custom generic getter Bifunction\r
85      * @param consumer the BiConsumer\r
86      * @param data the data structure storing retrieved deployed policies\r
87      *\r
88      * @return a map between pdp group and deployed versions of specified policy in that group\r
89      *\r
90      * @throws PfModelException the PfModel parsing exception\r
91      */\r
92     protected <T, R> Map<Pair<String, String>, T> collectDeployedPolicies(String policyId, PfConceptKey policyType,\r
93             BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
94 \r
95         List<PdpGroup> pdpGroups = getPolicyTypeFilteredPdpGroups(policyType);\r
96         hasActivePdpGroup(pdpGroups, policyType, policyId);\r
97         return constructDeployedPolicyMap(pdpGroups, policyId, policyType, getter, consumer, data);\r
98     }\r
99 \r
100     @FunctionalInterface\r
101     protected interface BiFunctionWithEx<T, U, R> {\r
102         public R apply(T value1, U value2) throws PfModelException;\r
103     }\r
104 \r
105     /**\r
106      * Checks if the list of pdp groups is empty. If so, throws exception saying specified policy deployment is not\r
107      * found in all existing pdp groups.\r
108      *\r
109      * @param pdpGroups the list of pdp groups to check against\r
110      * @param policyType the concept key of policy type\r
111      * @param policyId the ID of policy\r
112      *\r
113      * @throws PfModelException the PfModel parsing exception\r
114      */\r
115     private void hasActivePdpGroup(List<PdpGroup> pdpGroups, PfConceptKey policyType, String policyId)\r
116             throws PfModelException {\r
117 \r
118         if (pdpGroups.isEmpty()) {\r
119             throw new PfModelException(Response.Status.NOT_FOUND,\r
120                     constructDeploymentNotFoundMessage(policyType, policyId));\r
121         }\r
122     }\r
123 \r
124     /**\r
125      * Retrieves all pdp groups supporting specified policy type.\r
126      *\r
127      * @param policyTypeId the ID of policy type\r
128      * @param policyTypeVersion the version of policy type\r
129      *\r
130      * @return a list of pdp groups supporting specified policy type\r
131      *\r
132      * @throws PfModelException the PfModel parsing exception\r
133      */\r
134     private List<PdpGroup> getPolicyTypeFilteredPdpGroups(PfConceptKey policyType) throws PfModelException {\r
135 \r
136         List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>();\r
137         policyTypes.add(new ToscaPolicyTypeIdentifier(policyType.getName(), policyType.getVersion()));\r
138         PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder().policyTypeList(policyTypes).groupState(PdpState.ACTIVE)\r
139                 .pdpState(PdpState.ACTIVE).build();\r
140         return modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
141     }\r
142 \r
143     /**\r
144      * Constructs the map of deployed pdp groups and deployed policies.\r
145      *\r
146      * @param pdpGroups the list of pdp groups that contain the specified policy\r
147      * @param policyId the ID of policy\r
148      * @param policyType the concept key of policy type\r
149      * @param getter the custom generic getter BiFunction\r
150      * @param consumer the BiConsumer\r
151      * @param data the data structure storing retrieved deployed policies\r
152      *\r
153      * @return the constructed map of pdp groups and deployed policies\r
154      *\r
155      * @throws PfModelException the PfModel parsing exception\r
156      */\r
157     private <T, R> Map<Pair<String, String>, T> constructDeployedPolicyMap(List<PdpGroup> pdpGroups, String policyId,\r
158             PfConceptKey policyType, BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data)\r
159             throws PfModelException {\r
160 \r
161         Map<Pair<String, String>, T> deployedPolicyMap = new HashMap<>();\r
162         for (PdpGroup pdpGroup : pdpGroups) {\r
163             List<ToscaPolicyIdentifier> policyIdentifiers = extractPolicyIdentifiers(policyId, pdpGroup, policyType);\r
164             T deployedPolicies = getDeployedPolicies(policyIdentifiers, policyType, getter, consumer, data);\r
165             deployedPolicyMap.put(Pair.of(pdpGroup.getName(), pdpGroup.getVersion()), deployedPolicies);\r
166         }\r
167         return deployedPolicyMap;\r
168     }\r
169 \r
170     /**\r
171      * Extracts policy identifiers matching specified policy ID from specified pdp group.\r
172      *\r
173      * @param policyId the ID of policy to match\r
174      * @param pdpGroup the target pdp group to search\r
175      * @param policyType the concept key of policy type\r
176      *\r
177      * @return the list of policy identifiers\r
178      *\r
179      * @throws PfModelException the PfModel parsing exception\r
180      */\r
181     private List<ToscaPolicyIdentifier> extractPolicyIdentifiers(String policyId, PdpGroup pdpGroup,\r
182             PfConceptKey policyType) throws PfModelException {\r
183 \r
184         List<ToscaPolicyIdentifier> policyIdentifiers = new ArrayList<>();\r
185         for (PdpSubGroup pdpSubGroup : pdpGroup.getPdpSubgroups()) {\r
186             for (ToscaPolicyIdentifier policyIdentifier : pdpSubGroup.getPolicies()) {\r
187                 if (policyId.equalsIgnoreCase(policyIdentifier.getName())) {\r
188                     policyIdentifiers.add(policyIdentifier);\r
189                 }\r
190             }\r
191         }\r
192         if (policyIdentifiers.isEmpty()) {\r
193             throw new PfModelException(Response.Status.NOT_FOUND,\r
194                     constructDeploymentNotFoundMessage(policyType, policyId));\r
195         }\r
196         return policyIdentifiers;\r
197     }\r
198 \r
199     /**\r
200      * Retrieves deployed policies in a generic way.\r
201      *\r
202      * @param policyIdentifiers the identifiers of the policies to return\r
203      * @param policyType the concept key of current policy type\r
204      * @param getter the method reference of getting deployed policies\r
205      * @param consumer the method reference of consuming the returned policies\r
206      * @param data the data structure of deployed policies to return\r
207      *\r
208      * @return the generic type of policy data structure to return\r
209      *\r
210      * @throws PfModelException the PfModel parsing exception\r
211      */\r
212     private <T, R> T getDeployedPolicies(List<ToscaPolicyIdentifier> policyIdentifiers, PfConceptKey policyType,\r
213             BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
214 \r
215         for (ToscaPolicyIdentifier policyIdentifier : policyIdentifiers) {\r
216             R result = getter.apply(policyIdentifier.getName(),\r
217                     getTrimedVersionForLegacyType(policyIdentifier.getVersion(), policyType));\r
218             consumer.accept(data, result);\r
219         }\r
220         return data;\r
221     }\r
222 \r
223     /**\r
224      * Trims the version for legacy policies.\r
225      *\r
226      * @param fullVersion the full version format with major, minor, patch\r
227      * @param policyType the concept key of policy type\r
228      *\r
229      * @return the trimmed version\r
230      */\r
231     private String getTrimedVersionForLegacyType(String fullVersion, PfConceptKey policyType) {\r
232         return (policyType.getName().contains("guard") || policyType.getName().contains("Operational"))\r
233                 ? fullVersion.split("\\.")[0]\r
234                 : fullVersion;\r
235     }\r
236 \r
237     /**\r
238      * Constructs returned message for not found policy deployment.\r
239      *\r
240      * @param policyType the concept key of policy type\r
241      * @param policyId the ID of policy\r
242      *\r
243      * @return constructed message\r
244      */\r
245     private String constructDeploymentNotFoundMessage(PfConceptKey policyType, String policyId) {\r
246 \r
247         return "could not find policy with ID " + policyId + " and type " + policyType.getName() + ":"\r
248                 + policyType.getVersion() + " deployed in any pdp group";\r
249     }\r
250 }\r