Add common Jersey version
[policy/xacml-pdp.git] / applications / optimization / src / test / java / org / onap / policy / xacml / pdp / application / optimization / OptimizationPdpApplicationTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2019 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.xacml.pdp.application.optimization;
25
26 import static org.assertj.core.api.Assertions.assertThat;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.when;
29
30 import com.att.research.xacml.api.Response;
31 import com.google.common.collect.Lists;
32
33 import java.io.File;
34 import java.io.FileNotFoundException;
35 import java.io.IOException;
36 import java.nio.file.Files;
37 import java.nio.file.Paths;
38 import java.util.Collection;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Map.Entry;
43 import java.util.Properties;
44 import java.util.ServiceLoader;
45 import org.apache.commons.lang3.tuple.Pair;
46 import org.assertj.core.api.Condition;
47 import org.junit.BeforeClass;
48 import org.junit.ClassRule;
49 import org.junit.FixMethodOrder;
50 import org.junit.Test;
51 import org.junit.rules.TemporaryFolder;
52 import org.junit.runners.MethodSorters;
53 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
54 import org.onap.policy.common.utils.coder.CoderException;
55 import org.onap.policy.common.utils.coder.StandardCoder;
56 import org.onap.policy.common.utils.resources.ResourceUtils;
57 import org.onap.policy.common.utils.resources.TextFileUtils;
58 import org.onap.policy.models.decisions.concepts.DecisionRequest;
59 import org.onap.policy.models.decisions.concepts.DecisionResponse;
60 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
61 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
62 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
63 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
64 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
69 public class OptimizationPdpApplicationTest {
70
71     private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTest.class);
72     private static Properties properties = new Properties();
73     private static File propertiesFile;
74     private static XacmlApplicationServiceProvider service;
75     private static StandardCoder gson = new StandardCoder();
76     private static DecisionRequest baseRequest;
77     private static RestServerParameters clientParams;
78     private static String[] listPolicyTypeFiles = {
79         "onap.policies.Optimization",
80         "onap.policies.optimization.AffinityPolicy",
81         "onap.policies.optimization.DistancePolicy",
82         "onap.policies.optimization.HpaPolicy",
83         "onap.policies.optimization.OptimizationPolicy",
84         "onap.policies.optimization.PciPolicy",
85         "onap.policies.optimization.QueryPolicy",
86         "onap.policies.optimization.SubscriberPolicy",
87         "onap.policies.optimization.Vim_fit",
88         "onap.policies.optimization.VnfPolicy"};
89
90     @ClassRule
91     public static final TemporaryFolder policyFolder = new TemporaryFolder();
92
93     /**
94      * Copies the xacml.properties and policies files into
95      * temporary folder and loads the service provider saving
96      * instance of provider off for other tests to use.
97      */
98     @BeforeClass
99     public static void setUp() throws Exception {
100         clientParams = mock(RestServerParameters.class);
101         when(clientParams.getHost()).thenReturn("localhost");
102         when(clientParams.getPort()).thenReturn(6969);
103         //
104         // Load Single Decision Request
105         //
106         baseRequest = gson.decode(
107                 TextFileUtils
108                     .getTextFileAsString(
109                             "src/test/resources/decision.optimization.input.json"),
110                     DecisionRequest.class);
111         //
112         // Setup our temporary folder
113         //
114         XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
115         propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
116                 properties, myCreator);
117         //
118         // Copy the test policy types into data area
119         //
120         for (String policy : listPolicyTypeFiles) {
121             String policyType = ResourceUtils.getResourceAsString("policytypes/" + policy + ".yaml");
122             LOGGER.info("Copying {}", policyType);
123             Files.write(Paths.get(policyFolder.getRoot().getAbsolutePath(), policy + "-1.0.0.yaml"),
124                     policyType.getBytes());
125         }
126         //
127         // Load service
128         //
129         ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
130                 ServiceLoader.load(XacmlApplicationServiceProvider.class);
131         //
132         // Iterate through Xacml application services and find
133         // the optimization service. Save it for use throughout
134         // all the Junit tests.
135         //
136         StringBuilder strDump = new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
137         Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
138         while (iterator.hasNext()) {
139             XacmlApplicationServiceProvider application = iterator.next();
140             //
141             // Is it our service?
142             //
143             if (application instanceof OptimizationPdpApplication) {
144                 //
145                 // Should be the first and only one
146                 //
147                 assertThat(service).isNull();
148                 service = application;
149             }
150             strDump.append(application.applicationName());
151             strDump.append(" supports ");
152             strDump.append(application.supportedPolicyTypes());
153             strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
154         }
155         LOGGER.debug("{}", strDump);
156         assertThat(service).isNotNull();
157         //
158         // Tell it to initialize based on the properties file
159         // we just built for it.
160         //
161         service.initialize(propertiesFile.toPath().getParent(), clientParams);
162     }
163
164     @Test
165     public void test01Basics() {
166         //
167         // Make sure there's an application name
168         //
169         assertThat(service.applicationName()).isNotEmpty();
170         //
171         // Decisions
172         //
173         assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
174         assertThat(service.actionDecisionsSupported()).contains("optimize");
175         //
176         // Ensure it has the supported policy types and
177         // can support the correct policy types.
178         //
179         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
180                 "onap.policies.optimization.AffinityPolicy", "1.0.0"))).isTrue();
181         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
182                 "onap.foobar", "1.0.0"))).isFalse();
183     }
184
185     @Test
186     public void test02NoPolicies() {
187         //
188         // Ask for a decision when there are no policies loaded
189         //
190         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
191         LOGGER.info("Decision {}", decision.getKey());
192
193         assertThat(decision.getKey()).isNotNull();
194         assertThat(decision.getKey().getPolicies().size()).isEqualTo(0);
195     }
196
197     @Test
198     public void test03OptimizationDefault() throws CoderException, FileNotFoundException, IOException,
199         XacmlApplicationException {
200         //
201         // Now load all the optimization policies
202         //
203         TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service);
204         //
205         // Ask for a decision for default
206         //
207         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
208         LOGGER.info("Decision {}", decision.getKey());
209
210         assertThat(decision.getKey()).isNotNull();
211         assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
212         //
213         // Double check that the contents are what we expect
214         //
215         LOGGER.info(gson.encode(decision.getKey()));
216         //
217         // Validate it
218         //
219         validateDecision(decision.getKey(), baseRequest);
220     }
221
222     @SuppressWarnings("unchecked")
223     @Test
224     public void test04OptimizationDefaultGeography() throws CoderException {
225         //
226         // Add US to the geography list
227         //
228         ((List<String>)baseRequest.getResource().get("geography")).add("US");
229         //
230         // Ask for a decision for default US Policy
231         //
232         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
233         LOGGER.info("Decision {}", decision.getKey());
234
235         assertThat(decision.getKey()).isNotNull();
236         assertThat(decision.getKey().getPolicies().size()).isEqualTo(2);
237         //
238         // Double check that the contents are what we expect
239         //
240         LOGGER.info(gson.encode(decision.getKey()));
241         //
242         // Validate it
243         //
244         validateDecision(decision.getKey(), baseRequest);
245     }
246
247     @SuppressWarnings("unchecked")
248     @Test
249     public void test05OptimizationDefaultGeographyAndService() throws CoderException {
250         //
251         // Add vCPE to the service list
252         //
253         ((List<String>)baseRequest.getResource().get("services")).add("vCPE");
254         //
255         // Ask for a decision for default US policy for vCPE service
256         //
257         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
258         LOGGER.info("Decision {}", decision.getKey());
259
260         assertThat(decision.getKey()).isNotNull();
261         assertThat(decision.getKey().getPolicies().size()).isEqualTo(5);
262         //
263         // Double check that the contents are what we expect
264         //
265         LOGGER.info(gson.encode(decision.getKey()));
266         //
267         // Validate it
268         //
269         validateDecision(decision.getKey(), baseRequest);
270     }
271
272     @SuppressWarnings("unchecked")
273     @Test
274     public void test06OptimizationDefaultGeographyAndServiceAndResource() throws CoderException {
275         //
276         // Add vCPE to the service list
277         //
278         ((List<String>)baseRequest.getResource().get("resources")).add("vG");
279         //
280         // Ask for a decision for default US service vCPE resource vG policy
281         //
282         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
283         LOGGER.info("Decision {}", decision.getKey());
284
285         assertThat(decision.getKey()).isNotNull();
286         assertThat(decision.getKey().getPolicies().size()).isEqualTo(9);
287         //
288         // Double check that the contents are what we expect
289         //
290         LOGGER.info(gson.encode(decision.getKey()));
291         //
292         // Validate it
293         //
294         validateDecision(decision.getKey(), baseRequest);
295     }
296
297     @SuppressWarnings("unchecked")
298     @Test
299     public void test07OptimizationGeographyAndServiceAndResourceAndScope() throws CoderException {
300         //
301         // Add gold as a scope
302         //
303         ((List<String>)baseRequest.getResource().get("scope")).add("gold");
304         //
305         // Ask for a decision for specific US vCPE vG gold
306         //
307         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
308         LOGGER.info("Decision {}", decision.getKey());
309
310         assertThat(decision.getKey()).isNotNull();
311         assertThat(decision.getKey().getPolicies().size()).isEqualTo(10);
312         //
313         // Double check that the contents are what we expect
314         //
315         LOGGER.info(gson.encode(decision.getKey()));
316         //
317         // Validate it
318         //
319         validateDecision(decision.getKey(), baseRequest);
320     }
321
322     @SuppressWarnings("unchecked")
323     @Test
324     public void test08OptimizationGeographyAndServiceAndResourceAndScopeIsGoldOrPlatinum() throws CoderException {
325         //
326         // Add platinum to the scope list: this is now gold OR platinum
327         //
328         ((List<String>)baseRequest.getResource().get("scope")).add("platinum");
329         //
330         // Ask for a decision for specific US vCPE vG (gold or platinum)
331         //
332         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
333         LOGGER.info("Decision {}", decision.getKey());
334
335         assertThat(decision.getKey()).isNotNull();
336         assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
337         //
338         // Double check that the contents are what we expect
339         //
340         LOGGER.info(gson.encode(decision.getKey()));
341         //
342         // Validate it
343         //
344         validateDecision(decision.getKey(), baseRequest);
345     }
346
347     @SuppressWarnings("unchecked")
348     @Test
349     public void test09OptimizationGeographyAndServiceAndResourceAndScopeNotGold() throws CoderException {
350         //
351         // Add gold as a scope
352         //
353         ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
354         //
355         // Ask for a decision for specific US vCPE vG gold
356         //
357         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
358         LOGGER.info("Decision {}", decision.getKey());
359
360         assertThat(decision.getKey()).isNotNull();
361         assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
362         //
363         // Double check that the contents are what we expect
364         //
365         LOGGER.info(gson.encode(decision.getKey()));
366         //
367         // Validate it
368         //
369         validateDecision(decision.getKey(), baseRequest);
370     }
371
372     @Test
373     public void test10OptimizationPolicyTypeDefault() throws CoderException {
374         //
375         // Remove all the other resources from the request
376         //
377         cleanOutResources();
378         //
379         // Add in policy type
380         //
381         List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.AffinityPolicy");
382         baseRequest.getResource().put("policy-type", policyTypes);
383         //
384         // Ask for a decision for default
385         //
386         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
387         LOGGER.info("Decision {}", decision.getKey());
388
389         assertThat(decision.getKey()).isNotNull();
390         assertThat(decision.getKey().getPolicies().size()).isEqualTo(4);
391         //
392         // Double check that the contents are what we expect
393         //
394         LOGGER.info(gson.encode(decision.getKey()));
395     }
396
397     @Test
398     public void test20OptimizationPolicyTypeDefault() throws CoderException {
399         //
400         // Remove all the other resources from the request
401         //
402         cleanOutResources();
403         //
404         // Add in policy type
405         //
406         List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.HpaPolicy");
407         baseRequest.getResource().put("policy-type", policyTypes);
408         //
409         // Ask for a decision for default
410         //
411         Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
412         LOGGER.info("Decision {}", decision.getKey());
413
414         assertThat(decision.getKey()).isNotNull();
415         assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
416         //
417         // Double check that the contents are what we expect
418         //
419         LOGGER.info(gson.encode(decision.getKey()));
420     }
421
422     @SuppressWarnings("unchecked")
423     private void validateDecision(DecisionResponse decision, DecisionRequest request) {
424         for (Entry<String, Object> entrySet : decision.getPolicies().entrySet()) {
425             LOGGER.info("Decision Returned Policy {}", entrySet.getKey());
426             assertThat(entrySet.getValue()).isInstanceOf(Map.class);
427             Map<String, Object> policyContents = (Map<String, Object>) entrySet.getValue();
428             assertThat(policyContents.containsKey("properties")).isTrue();
429             assertThat(policyContents.get("properties")).isInstanceOf(Map.class);
430             Map<String, Object> policyProperties = (Map<String, Object>) policyContents.get("properties");
431
432             validateMatchable((Collection<String>) request.getResource().get("scope"),
433                     (Collection<String>) policyProperties.get("scope"));
434
435             validateMatchable((Collection<String>) request.getResource().get("services"),
436                     (Collection<String>) policyProperties.get("services"));
437
438             validateMatchable((Collection<String>) request.getResource().get("resources"),
439                     (Collection<String>) policyProperties.get("resources"));
440
441             validateMatchable((Collection<String>) request.getResource().get("geography"),
442                     (Collection<String>) policyProperties.get("geography"));
443         }
444     }
445
446     private void validateMatchable(Collection<String> requestList, Collection<String> policyProperties) {
447         LOGGER.info("Validating matchable: {} with {}", policyProperties, requestList);
448         //
449         // Null or empty implies '*' - that is any value is acceptable
450         // for this policy.
451         //
452         if (policyProperties == null || policyProperties.isEmpty()) {
453             return;
454         }
455         Condition<String> condition = new Condition<>(
456                 requestList::contains,
457                 "Request list is contained");
458         assertThat(policyProperties).haveAtLeast(1, condition);
459
460     }
461
462     @SuppressWarnings("unchecked")
463     private void cleanOutResources() {
464         ((List<String>)baseRequest.getResource().get("scope")).clear();
465         ((List<String>)baseRequest.getResource().get("services")).clear();
466         ((List<String>)baseRequest.getResource().get("resources")).clear();
467         ((List<String>)baseRequest.getResource().get("geography")).clear();
468     }
469 }