4b7c3133b87b2273604454756192b14d51b4ff67
[policy/api.git] / main / src / test / java / org / onap / policy / api / main / rest / provider / TestPolicyProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy API
4  * ================================================================================
5  * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * SPDX-License-Identifier: Apache-2.0
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.policy.api.main.rest.provider;
25
26 import static org.assertj.core.api.Assertions.assertThatCode;
27 import static org.assertj.core.api.Assertions.assertThatThrownBy;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.fail;
32
33 import java.util.ArrayList;
34 import java.util.Base64;
35 import java.util.Collections;
36 import java.util.List;
37
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.onap.policy.api.main.parameters.ApiParameterGroup;
42 import org.onap.policy.common.parameters.ParameterService;
43 import org.onap.policy.common.utils.coder.CoderException;
44 import org.onap.policy.common.utils.coder.StandardCoder;
45 import org.onap.policy.common.utils.coder.StandardYamlCoder;
46 import org.onap.policy.common.utils.resources.ResourceUtils;
47 import org.onap.policy.models.base.PfModelException;
48 import org.onap.policy.models.pdp.concepts.Pdp;
49 import org.onap.policy.models.pdp.concepts.PdpGroup;
50 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
51 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
52 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
53 import org.onap.policy.models.pdp.enums.PdpState;
54 import org.onap.policy.models.provider.PolicyModelsProvider;
55 import org.onap.policy.models.provider.PolicyModelsProviderFactory;
56 import org.onap.policy.models.provider.PolicyModelsProviderParameters;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
60
61 /**
62  * This class performs unit test of {@link PolicyProvider}.
63  *
64  * @author Chenfei Gao (cgao@research.att.com)
65  */
66 public class TestPolicyProvider {
67
68     private static PolicyProvider policyProvider;
69     private static PolicyTypeProvider policyTypeProvider;
70     private static PolicyModelsProviderParameters providerParams;
71     private static ApiParameterGroup apiParamGroup;
72     private static StandardCoder standardCoder;
73     private static StandardYamlCoder standardYamlCoder;
74
75     private static final String POLICY_RESOURCE = "policies/vCPE.policy.monitoring.input.tosca.json";
76     private static final String POLICY_TYPE_RESOURCE = "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml";
77     private static final String POLICY_RESOURCE_WITH_BAD_POLICYTYPE_ID = "policies/vCPE.policy.bad.policytypeid.json";
78     private static final String POLICY_RESOURCE_WITH_BAD_POLICYTYPE_VERSION =
79             "policies/vCPE.policy.bad.policytypeversion.json";
80     private static final String POLICY_RESOURCE_WITH_NO_POLICY_VERSION = "policies/vCPE.policy.no.policyversion.json";
81     private static final String POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION =
82             "policies/vCPE.policy.duplicate.policyversion.json";
83     private static final String MULTIPLE_POLICIES_RESOURCE = "policies/vCPE.policies.optimization.input.tosca.json";
84
85     public static final String POLICY_TYPE_RESOURCE_OPERATIONAL =
86             "policytypes/onap.policies.controlloop.operational.Common.yaml";
87     private static final String POLICY_RESOURCE_OPERATIONAL = "policies/vCPE.policy.operational.input.tosca.json";
88     public static final String POLICY_TYPE_OPERATIONAL_DROOLS = "onap.policies.controlloop.operational.common.Drools";
89
90
91     // @formatter:off
92     private String[] toscaPolicyTypeResourceNames = {
93         "policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml",
94         "policytypes/onap.policies.optimization.resource.DistancePolicy.yaml",
95         "policytypes/onap.policies.optimization.resource.HpaPolicy.yaml",
96         "policytypes/onap.policies.optimization.service.QueryPolicy.yaml",
97         "policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml",
98         "policytypes/onap.policies.optimization.resource.Vim_fit.yaml",
99         "policytypes/onap.policies.optimization.resource.VnfPolicy.yaml",
100         "policytypes/onap.policies.monitoring.cdap.tca.hi.lo.app.yaml"
101     };
102     // @formatter:on
103
104     /**
105      * Initializes parameters.
106      *
107      * @throws PfModelException the PfModel parsing exception
108      */
109     @Before
110     public void setupParameters() throws PfModelException {
111
112         standardCoder = new StandardCoder();
113         standardYamlCoder = new StandardYamlCoder();
114         providerParams = new PolicyModelsProviderParameters();
115         providerParams.setDatabaseDriver("org.h2.Driver");
116         providerParams.setDatabaseUrl("jdbc:h2:mem:testdb");
117         providerParams.setDatabaseUser("policy");
118         providerParams.setDatabasePassword(Base64.getEncoder().encodeToString("P01icY".getBytes()));
119         providerParams.setPersistenceUnit("ToscaConceptTest");
120         apiParamGroup = new ApiParameterGroup("ApiGroup", null, providerParams, Collections.emptyList());
121         ParameterService.register(apiParamGroup, true);
122         policyTypeProvider = new PolicyTypeProvider();
123         policyProvider = new PolicyProvider();
124     }
125
126     /**
127      * Closes up DB connections and deregisters API parameter group.
128      *
129      * @throws PfModelException the PfModel parsing exception
130      */
131     @After
132     public void tearDown() throws PfModelException {
133
134         policyTypeProvider.close();
135         policyProvider.close();
136         ParameterService.deregister(apiParamGroup);
137     }
138
139     @Test
140     public void testFetchPolicies() {
141
142         assertThatThrownBy(() -> {
143             policyProvider.fetchPolicies("dummy", "1.0.0", null, null);
144         }).hasMessage("policy with ID null:null and type dummy:1.0.0 does not exist");
145
146         assertThatThrownBy(() -> {
147             policyProvider.fetchPolicies("dummy", "1.0.0", "dummy", null);
148         }).hasMessage("policy with ID dummy:null and type dummy:1.0.0 does not exist");
149
150         assertThatThrownBy(() -> {
151             policyProvider.fetchPolicies("dummy", "1.0.0", "dummy", "1.0.0");
152         }).hasMessage("policy with ID dummy:1.0.0 and type dummy:1.0.0 does not exist");
153     }
154
155     @Test
156     public void testFetchLatestPolicies() {
157
158         assertThatThrownBy(() -> {
159             policyProvider.fetchLatestPolicies("dummy", "dummy", "dummy");
160         }).hasMessage("policy with ID dummy:null and type dummy:dummy does not exist");
161     }
162
163
164     @Test
165     public void testFetchDeployedPolicies() {
166         String policyId = "onap.restart.tca";
167         String policyVersion = "1.0.0";
168         String policyTypeVersion = "1.0.0";
169         String policyTypeId = "onap.policies.monitoring.cdap.tca.hi.lo.app";
170
171         // Basic Exception Throw
172         assertThatThrownBy(() -> {
173             policyProvider.fetchDeployedPolicies("dummy", "1.0.0", "dummy");
174         }).hasMessage("could not find policy with ID dummy and type dummy:1.0.0 deployed in any pdp group");
175
176         try (PolicyModelsProvider databaseProvider =
177                 new PolicyModelsProviderFactory().createPolicyModelsProvider(providerParams)) {
178             assertEquals(0, databaseProvider.getPdpGroups("name").size());
179             assertEquals(0, databaseProvider.getFilteredPdpGroups(PdpGroupFilter.builder().build()).size());
180
181             assertNotNull(databaseProvider.createPdpGroups(new ArrayList<>()));
182             assertNotNull(databaseProvider.updatePdpGroups(new ArrayList<>()));
183
184             PdpGroup pdpGroup = new PdpGroup();
185             pdpGroup.setName("group");
186             pdpGroup.setVersion("1.2.3");
187             pdpGroup.setPdpGroupState(PdpState.ACTIVE);
188             pdpGroup.setPdpSubgroups(new ArrayList<>());
189             List<PdpGroup> groupList = new ArrayList<>();
190             groupList.add(pdpGroup);
191
192             PdpSubGroup pdpSubGroup = new PdpSubGroup();
193             pdpSubGroup.setPdpType("type");
194             pdpSubGroup.setDesiredInstanceCount(123);
195             pdpSubGroup.setSupportedPolicyTypes(new ArrayList<>());
196             pdpSubGroup.getSupportedPolicyTypes().add(new ToscaPolicyTypeIdentifier(policyTypeId, policyTypeVersion));
197             pdpGroup.getPdpSubgroups().add(pdpSubGroup);
198
199             Pdp pdp = new Pdp();
200             pdp.setInstanceId("type-0");
201             pdp.setMessage("Hello");
202             pdp.setPdpState(PdpState.ACTIVE);
203             pdp.setHealthy(PdpHealthStatus.UNKNOWN);
204             pdpSubGroup.setPdpInstances(new ArrayList<>());
205             pdpSubGroup.getPdpInstances().add(pdp);
206
207             // Create Pdp Groups
208             assertEquals(123, databaseProvider.createPdpGroups(groupList).get(0).getPdpSubgroups().get(0)
209                     .getDesiredInstanceCount());
210             assertEquals(1, databaseProvider.getPdpGroups("group").size());
211
212             // Create Policy Type
213             assertThatCode(() -> {
214                 ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode(
215                         ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class);
216                 policyTypeProvider.createPolicyType(policyTypeServiceTemplate);
217             }).doesNotThrowAnyException();
218
219             // Create Policy
220             assertThatCode(() -> {
221                 String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE);
222                 ToscaServiceTemplate policyServiceTemplate =
223                         standardCoder.decode(policyString, ToscaServiceTemplate.class);
224                 ToscaServiceTemplate serviceTemplate =
225                         policyProvider.createPolicy(policyTypeId, policyTypeVersion, policyServiceTemplate);
226                 assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty());
227             }).doesNotThrowAnyException();
228
229             // Test fetchDeployedPolicies (deployedPolicyMap.isEmpty())==true
230             assertThatThrownBy(() -> {
231                 policyProvider.fetchDeployedPolicies(policyTypeId, policyTypeVersion, policyId);
232             })  .hasMessage("could not find policy with ID " + policyId + " and type " + policyTypeId + ":"
233                     + policyTypeVersion + " deployed in any pdp group");
234
235
236             // Update pdpSubGroup
237             pdpSubGroup.setPolicies(new ArrayList<>());
238             pdpSubGroup.getPolicies().add(new ToscaPolicyIdentifier(policyId, policyVersion));
239             assertEquals(1,
240                     databaseProvider.createPdpGroups(groupList).get(0).getPdpSubgroups().get(0).getPolicies().size());
241
242             // Test fetchDeployedPolicies
243             assertThatCode(() -> {
244                 policyProvider.fetchDeployedPolicies(policyTypeId, policyTypeVersion, policyId);
245             }).doesNotThrowAnyException();
246
247             // Test validateDeleteEligibility exception path(!pdpGroups.isEmpty())
248             assertThatThrownBy(() -> {
249                 policyProvider.deletePolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", "onap.restart.tca",
250                         "1.0.0");
251             })  .hasMessageContaining("policy with ID " + policyId + ":" + policyVersion
252                     + " cannot be deleted as it is deployed in pdp groups");
253         } catch (Exception exc) {
254             fail("Test should not throw an exception");
255         }
256     }
257
258     @Test
259     public void testCreatePolicy() throws Exception {
260
261         assertThatThrownBy(() -> {
262             policyProvider.createPolicy("dummy", "1.0.0", new ToscaServiceTemplate());
263         }).hasMessage("policy type with ID dummy:1.0.0 does not exist");
264
265         ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode(
266                 ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class);
267         policyTypeProvider.createPolicyType(policyTypeServiceTemplate);
268
269         assertThatThrownBy(() -> {
270             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_BAD_POLICYTYPE_ID);
271             ToscaServiceTemplate badPolicyServiceTemplate =
272                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
273             policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0",
274                     badPolicyServiceTemplate);
275         }).hasMessage("policy type id does not match");
276
277         assertThatThrownBy(() -> {
278             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_BAD_POLICYTYPE_VERSION);
279             ToscaServiceTemplate badPolicyServiceTemplate =
280                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
281             policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0",
282                     badPolicyServiceTemplate);
283         }).hasMessage("policy type version does not match");
284
285         assertThatThrownBy(() -> {
286             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_NO_POLICY_VERSION);
287             ToscaServiceTemplate badPolicyServiceTemplate =
288                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
289             policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0",
290                     badPolicyServiceTemplate);
291         }).hasMessage("mandatory 'version' field is missing in policies: onap.restart.tca");
292
293         assertThatThrownBy(() -> {
294             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION);
295             ToscaServiceTemplate badPolicyServiceTemplate =
296                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
297             policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0",
298                     badPolicyServiceTemplate);
299         }).hasMessage("the same version of policies 'onap.restart.tca:1.0.0' appear multiple times in the payload");
300
301         String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE);
302         ToscaServiceTemplate policyServiceTemplate = standardCoder.decode(policyString, ToscaServiceTemplate.class);
303         ToscaServiceTemplate serviceTemplate = policyProvider
304                 .createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate);
305         assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty());
306
307         assertThatThrownBy(() -> {
308             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE);
309             ToscaServiceTemplate badPolicyServiceTemplate =
310                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
311             policyProvider.createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0",
312                     badPolicyServiceTemplate);
313         }).hasMessage("policy onap.restart.tca:1.0.0 already exists; its latest version is 1.0.0");
314     }
315
316     @Test
317     public void testCreateOperationalDroolsPolicy() throws CoderException, PfModelException {
318         ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode(
319                 ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE_OPERATIONAL), ToscaServiceTemplate.class);
320         policyTypeProvider.createPolicyType(policyTypeServiceTemplate);
321
322         String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_OPERATIONAL);
323         ToscaServiceTemplate policyServiceTemplate = standardCoder.decode(policyString, ToscaServiceTemplate.class);
324         ToscaServiceTemplate serviceTemplate =
325                 policyProvider.createPolicy(POLICY_TYPE_OPERATIONAL_DROOLS, "1.0.0", policyServiceTemplate);
326         assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty());
327     }
328
329     @Test
330     public void testSimpleCreatePolicy() throws Exception {
331
332         String errorMessage = "policy type onap.policies.optimization.resource.AffinityPolicy:1.0.0 for "
333             + "policy OSDF_CASABLANCA.Affinity_Default:1.0.0 does not exist";
334         assertThatThrownBy(() -> {
335             String multiPoliciesString = ResourceUtils.getResourceAsString(MULTIPLE_POLICIES_RESOURCE);
336             ToscaServiceTemplate multiPoliciesServiceTemplate =
337                     standardCoder.decode(multiPoliciesString, ToscaServiceTemplate.class);
338             policyProvider.createPolicies(multiPoliciesServiceTemplate);
339         }).hasMessage(errorMessage);
340
341         // Create required policy types
342         for (String policyTypeName : toscaPolicyTypeResourceNames) {
343             ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode(
344                     ResourceUtils.getResourceAsString(policyTypeName), ToscaServiceTemplate.class);
345             policyTypeProvider.createPolicyType(policyTypeServiceTemplate);
346         }
347
348         // Create multiple policies in one call
349         String multiPoliciesString = ResourceUtils.getResourceAsString(MULTIPLE_POLICIES_RESOURCE);
350         ToscaServiceTemplate multiPoliciesServiceTemplate =
351                 standardCoder.decode(multiPoliciesString, ToscaServiceTemplate.class);
352         policyProvider.createPolicies(multiPoliciesServiceTemplate);
353
354         assertThatThrownBy(() -> {
355             String badPolicyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE_WITH_DUPLICATE_POLICY_VERSION);
356             ToscaServiceTemplate badPolicyServiceTemplate =
357                     standardCoder.decode(badPolicyString, ToscaServiceTemplate.class);
358             policyProvider.createPolicies(badPolicyServiceTemplate);
359         }).hasMessage("the same version of policies 'onap.restart.tca:1.0.0' appear multiple times in the payload");
360     }
361
362     @Test
363     public void testDeletePolicy() {
364
365         assertThatThrownBy(() -> {
366             policyProvider.deletePolicy("dummy", "1.0.0", "dummy", "1.0.0");
367         }).hasMessage("policy with ID dummy:1.0.0 and type dummy:1.0.0 does not exist");
368
369         assertThatCode(() -> {
370             ToscaServiceTemplate policyTypeServiceTemplate = standardYamlCoder.decode(
371                     ResourceUtils.getResourceAsString(POLICY_TYPE_RESOURCE), ToscaServiceTemplate.class);
372             policyTypeProvider.createPolicyType(policyTypeServiceTemplate);
373         }).doesNotThrowAnyException();
374
375         assertThatCode(() -> {
376             String policyString = ResourceUtils.getResourceAsString(POLICY_RESOURCE);
377             ToscaServiceTemplate policyServiceTemplate = standardCoder.decode(policyString, ToscaServiceTemplate.class);
378             ToscaServiceTemplate serviceTemplate = policyProvider
379                     .createPolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", policyServiceTemplate);
380             assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty());
381         }).doesNotThrowAnyException();
382
383         assertThatCode(() -> {
384             ToscaServiceTemplate serviceTemplate = policyProvider
385                     .deletePolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", "onap.restart.tca", "1.0.0");
386             assertFalse(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).isEmpty());
387         }).doesNotThrowAnyException();
388
389         String exceptionMessage = "policy with ID onap.restart.tca:1.0.0 and type "
390                 + "onap.policies.monitoring.cdap.tca.hi.lo.app:1.0.0 does not exist";
391         assertThatThrownBy(() -> {
392             policyProvider.deletePolicy("onap.policies.monitoring.cdap.tca.hi.lo.app", "1.0.0", "onap.restart.tca",
393                     "1.0.0");
394         }).hasMessage(exceptionMessage);
395     }
396
397 }