03f46b9e9741fccc221a49b5c3e00cf081c29c4d
[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 import javax.ws.rs.core.Response;\r
32 import org.apache.commons.lang3.tuple.Pair;\r
33 import org.onap.policy.api.main.parameters.ApiParameterGroup;\r
34 import org.onap.policy.common.parameters.ParameterService;\r
35 import org.onap.policy.models.base.PfConceptKey;\r
36 import org.onap.policy.models.base.PfModelException;\r
37 import org.onap.policy.models.pdp.concepts.PdpGroup;\r
38 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;\r
39 import org.onap.policy.models.pdp.concepts.PdpSubGroup;\r
40 import org.onap.policy.models.pdp.enums.PdpState;\r
41 import org.onap.policy.models.provider.PolicyModelsProvider;\r
42 import org.onap.policy.models.provider.PolicyModelsProviderFactory;\r
43 import org.onap.policy.models.provider.PolicyModelsProviderParameters;\r
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;\r
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;\r
46 \r
47 /**\r
48  * Super class for providers that use a model provider.\r
49  */\r
50 public class CommonModelProvider implements AutoCloseable {\r
51 \r
52     protected final PolicyModelsProvider modelsProvider;\r
53 \r
54     /**\r
55      * Constructs the object, populating {@link #modelsProvider}.\r
56      *\r
57      * @throws PfModelException if an error occurs\r
58      */\r
59     public CommonModelProvider() throws PfModelException {\r
60 \r
61         ApiParameterGroup parameterGroup = ParameterService.get("ApiGroup");\r
62         PolicyModelsProviderParameters providerParameters = parameterGroup.getDatabaseProviderParameters();\r
63         modelsProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(providerParameters);\r
64     }\r
65 \r
66     /**\r
67      * Closes the connection to database.\r
68      *\r
69      * @throws PfModelException the PfModel parsing exception\r
70      */\r
71     @Override\r
72     public void close() throws PfModelException {\r
73 \r
74         modelsProvider.close();\r
75     }\r
76 \r
77     /**\r
78      * Collects all deployed versions of specified policy in all pdp groups.\r
79      *\r
80      * @param policyId the ID of policy\r
81      * @param policyType the concept key of policy type\r
82      * @param getter the custom generic getter Bifunction\r
83      * @param consumer the BiConsumer\r
84      * @param data the data structure storing retrieved deployed policies\r
85      *\r
86      * @return a map between pdp group and deployed versions of specified policy in that group\r
87      *\r
88      * @throws PfModelException the PfModel parsing exception\r
89      */\r
90     protected <T, R> Map<Pair<String, String>, T> collectDeployedPolicies(String policyId, PfConceptKey policyType,\r
91             BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
92 \r
93         List<PdpGroup> pdpGroups = getPolicyTypeFilteredPdpGroups(policyType);\r
94         hasActivePdpGroup(pdpGroups, policyType, policyId);\r
95         return constructDeployedPolicyMap(pdpGroups, policyId, policyType, getter, consumer, data);\r
96     }\r
97 \r
98     @FunctionalInterface\r
99     protected interface BiFunctionWithEx<T, U, R> {\r
100         public R apply(T value1, U value2) throws PfModelException;\r
101     }\r
102 \r
103     /**\r
104      * Checks if the list of pdp groups is empty. If so, throws exception saying specified policy deployment is not\r
105      * found in all existing pdp groups.\r
106      *\r
107      * @param pdpGroups the list of pdp groups to check against\r
108      * @param policyType the concept key of policy type\r
109      * @param policyId the ID of policy\r
110      *\r
111      * @throws PfModelException the PfModel parsing exception\r
112      */\r
113     private void hasActivePdpGroup(List<PdpGroup> pdpGroups, PfConceptKey policyType, String policyId)\r
114             throws PfModelException {\r
115 \r
116         if (pdpGroups.isEmpty()) {\r
117             throw new PfModelException(Response.Status.NOT_FOUND,\r
118                     constructDeploymentNotFoundMessage(policyType, policyId));\r
119         }\r
120     }\r
121 \r
122     /**\r
123      * Retrieves all pdp groups supporting specified policy type.\r
124      *\r
125      * @param policyTypeId the ID of policy type\r
126      * @param policyTypeVersion the version of policy type\r
127      *\r
128      * @return a list of pdp groups supporting specified policy type\r
129      *\r
130      * @throws PfModelException the PfModel parsing exception\r
131      */\r
132     private List<PdpGroup> getPolicyTypeFilteredPdpGroups(PfConceptKey policyType) throws PfModelException {\r
133 \r
134         List<ToscaPolicyTypeIdentifier> policyTypes = new ArrayList<>();\r
135         policyTypes.add(new ToscaPolicyTypeIdentifier(policyType.getName(), policyType.getVersion()));\r
136         PdpGroupFilter pdpGroupFilter = PdpGroupFilter.builder().policyTypeList(policyTypes).groupState(PdpState.ACTIVE)\r
137                 .pdpState(PdpState.ACTIVE).build();\r
138         return modelsProvider.getFilteredPdpGroups(pdpGroupFilter);\r
139     }\r
140 \r
141     /**\r
142      * Constructs the map of deployed pdp groups and deployed policies.\r
143      *\r
144      * @param pdpGroups the list of pdp groups that contain the specified policy\r
145      * @param policyId the ID of policy\r
146      * @param policyType the concept key of policy type\r
147      * @param getter the custom generic getter BiFunction\r
148      * @param consumer the BiConsumer\r
149      * @param data the data structure storing retrieved deployed policies\r
150      *\r
151      * @return the constructed map of pdp groups and deployed policies\r
152      *\r
153      * @throws PfModelException the PfModel parsing exception\r
154      */\r
155     private <T, R> Map<Pair<String, String>, T> constructDeployedPolicyMap(List<PdpGroup> pdpGroups, String policyId,\r
156             PfConceptKey policyType, BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data)\r
157             throws PfModelException {\r
158 \r
159         Map<Pair<String, String>, T> deployedPolicyMap = new HashMap<>();\r
160         for (PdpGroup pdpGroup : pdpGroups) {\r
161             List<ToscaPolicyIdentifier> policyIdentifiers = extractPolicyIdentifiers(policyId, pdpGroup, policyType);\r
162             T deployedPolicies = getDeployedPolicies(policyIdentifiers, policyType, getter, consumer, data);\r
163             deployedPolicyMap.put(Pair.of(pdpGroup.getName(), pdpGroup.getVersion()), deployedPolicies);\r
164         }\r
165         return deployedPolicyMap;\r
166     }\r
167 \r
168     /**\r
169      * Extracts policy identifiers matching specified policy ID from specified pdp group.\r
170      *\r
171      * @param policyId the ID of policy to match\r
172      * @param pdpGroup the target pdp group to search\r
173      * @param policyType the concept key of policy type\r
174      *\r
175      * @return the list of policy identifiers\r
176      *\r
177      * @throws PfModelException the PfModel parsing exception\r
178      */\r
179     private List<ToscaPolicyIdentifier> extractPolicyIdentifiers(String policyId, PdpGroup pdpGroup,\r
180             PfConceptKey policyType) throws PfModelException {\r
181 \r
182         List<ToscaPolicyIdentifier> policyIdentifiers = new ArrayList<>();\r
183         for (PdpSubGroup pdpSubGroup : pdpGroup.getPdpSubgroups()) {\r
184             for (ToscaPolicyIdentifier policyIdentifier : pdpSubGroup.getPolicies()) {\r
185                 if (policyId.equalsIgnoreCase(policyIdentifier.getName())) {\r
186                     policyIdentifiers.add(policyIdentifier);\r
187                 }\r
188             }\r
189         }\r
190         if (policyIdentifiers.isEmpty()) {\r
191             throw new PfModelException(Response.Status.NOT_FOUND,\r
192                     constructDeploymentNotFoundMessage(policyType, policyId));\r
193         }\r
194         return policyIdentifiers;\r
195     }\r
196 \r
197     /**\r
198      * Retrieves deployed policies in a generic way.\r
199      *\r
200      * @param policyIdentifiers the identifiers of the policies to return\r
201      * @param policyType the concept key of current policy type\r
202      * @param getter the method reference of getting deployed policies\r
203      * @param consumer the method reference of consuming the returned policies\r
204      * @param data the data structure of deployed policies to return\r
205      *\r
206      * @return the generic type of policy data structure to return\r
207      *\r
208      * @throws PfModelException the PfModel parsing exception\r
209      */\r
210     private <T, R> T getDeployedPolicies(List<ToscaPolicyIdentifier> policyIdentifiers, PfConceptKey policyType,\r
211             BiFunctionWithEx<String, String, R> getter, BiConsumer<T, R> consumer, T data) throws PfModelException {\r
212 \r
213         for (ToscaPolicyIdentifier policyIdentifier : policyIdentifiers) {\r
214             R result = getter.apply(policyIdentifier.getName(),\r
215                     getTrimedVersionForLegacyType(policyIdentifier.getVersion(), policyType));\r
216             consumer.accept(data, result);\r
217         }\r
218         return data;\r
219     }\r
220 \r
221     /**\r
222      * Trims the version for legacy policies.\r
223      *\r
224      * @param fullVersion the full version format with major, minor, patch\r
225      * @param policyType the concept key of policy type\r
226      *\r
227      * @return the trimmed version\r
228      */\r
229     private String getTrimedVersionForLegacyType(String fullVersion, PfConceptKey policyType) {\r
230         return (policyType.getName().contains("guard") || policyType.getName().contains("Operational"))\r
231                 ? fullVersion.split("\\.")[0]\r
232                 : fullVersion;\r
233     }\r
234 \r
235     /**\r
236      * Constructs returned message for not found policy deployment.\r
237      *\r
238      * @param policyType the concept key of policy type\r
239      * @param policyId the ID of policy\r
240      *\r
241      * @return constructed message\r
242      */\r
243     private String constructDeploymentNotFoundMessage(PfConceptKey policyType, String policyId) {\r
244 \r
245         return "could not find policy with ID " + policyId + " and type " + policyType.getName() + ":"\r
246                 + policyType.getVersion() + " deployed in any pdp group";\r
247     }\r
248 }\r