2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * SPDX-License-Identifier: Apache-2.0
21 * ============LICENSE_END=========================================================
24 package org.onap.policy.xacml.pdp.application.optimization;
26 import static org.assertj.core.api.Assertions.assertThat;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.when;
30 import com.att.research.xacml.api.Response;
31 import com.google.common.collect.Lists;
33 import java.nio.file.Files;
34 import java.nio.file.Paths;
35 import java.util.Collection;
36 import java.util.Iterator;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import java.util.Properties;
41 import java.util.ServiceLoader;
42 import org.apache.commons.lang3.tuple.Pair;
43 import org.assertj.core.api.Condition;
44 import org.junit.BeforeClass;
45 import org.junit.ClassRule;
46 import org.junit.FixMethodOrder;
47 import org.junit.Test;
48 import org.junit.rules.TemporaryFolder;
49 import org.junit.runners.MethodSorters;
50 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
51 import org.onap.policy.common.utils.coder.CoderException;
52 import org.onap.policy.common.utils.coder.StandardCoder;
53 import org.onap.policy.common.utils.resources.ResourceUtils;
54 import org.onap.policy.common.utils.resources.TextFileUtils;
55 import org.onap.policy.models.decisions.concepts.DecisionRequest;
56 import org.onap.policy.models.decisions.concepts.DecisionResponse;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
58 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
59 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
60 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
61 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
66 public class OptimizationPdpApplicationTest {
68 private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTest.class);
69 private static Properties properties = new Properties();
70 private static File propertiesFile;
71 private static XacmlApplicationServiceProvider service;
72 private static StandardCoder gson = new StandardCoder();
73 private static DecisionRequest baseRequest;
74 private static RestServerParameters clientParams;
75 private static String[] listPolicyTypeFiles = {
76 "onap.policies.Optimization",
77 "onap.policies.optimization.Resource",
78 "onap.policies.optimization.Service",
79 "onap.policies.optimization.resource.AffinityPolicy",
80 "onap.policies.optimization.resource.DistancePolicy",
81 "onap.policies.optimization.resource.HpaPolicy",
82 "onap.policies.optimization.resource.OptimizationPolicy",
83 "onap.policies.optimization.resource.PciPolicy",
84 "onap.policies.optimization.service.QueryPolicy",
85 "onap.policies.optimization.service.SubscriberPolicy",
86 "onap.policies.optimization.resource.Vim_fit",
87 "onap.policies.optimization.resource.VnfPolicy"};
90 public static final TemporaryFolder policyFolder = new TemporaryFolder();
93 * Copies the xacml.properties and policies files into
94 * temporary folder and loads the service provider saving
95 * instance of provider off for other tests to use.
98 public static void setUp() throws Exception {
99 clientParams = mock(RestServerParameters.class);
100 when(clientParams.getHost()).thenReturn("localhost");
101 when(clientParams.getPort()).thenReturn(6969);
103 // Load Single Decision Request
105 baseRequest = gson.decode(
107 .getTextFileAsString(
108 "src/test/resources/decision.optimization.input.json"),
109 DecisionRequest.class);
111 // Setup our temporary folder
113 XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
114 propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
115 properties, myCreator);
117 // Copy the test policy types into data area
119 for (String policy : listPolicyTypeFiles) {
120 String policyType = ResourceUtils.getResourceAsString("policytypes/" + policy + ".yaml");
121 LOGGER.info("Copying {}", policyType);
122 Files.write(Paths.get(policyFolder.getRoot().getAbsolutePath(), policy + "-1.0.0.yaml"),
123 policyType.getBytes());
128 ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
129 ServiceLoader.load(XacmlApplicationServiceProvider.class);
131 // Iterate through Xacml application services and find
132 // the optimization service. Save it for use throughout
133 // all the Junit tests.
135 StringBuilder strDump = new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
136 Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
137 while (iterator.hasNext()) {
138 XacmlApplicationServiceProvider application = iterator.next();
140 // Is it our service?
142 if (application instanceof OptimizationPdpApplication) {
144 // Should be the first and only one
146 assertThat(service).isNull();
147 service = application;
149 strDump.append(application.applicationName());
150 strDump.append(" supports ");
151 strDump.append(application.supportedPolicyTypes());
152 strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
154 LOGGER.debug("{}", strDump);
155 assertThat(service).isNotNull();
157 // Tell it to initialize based on the properties file
158 // we just built for it.
160 service.initialize(propertiesFile.toPath().getParent(), clientParams);
164 * Simply test some of the simple methods for the application.
167 public void test01Basics() {
169 // Make sure there's an application name
171 assertThat(service.applicationName()).isNotEmpty();
173 // Does it return the correct decisions
175 assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
176 assertThat(service.actionDecisionsSupported()).contains("optimize");
178 // Ensure it has the supported policy types and
179 // can support the correct policy types.
181 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
182 "onap.policies.optimization.resource.AffinityPolicy", "1.0.0"))).isTrue();
183 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
184 "onap.policies.optimization.service.SubscriberPolicy", "1.0.0"))).isTrue();
185 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
186 "onap.foobar", "1.0.0"))).isFalse();
190 * With no policies loaded, there should be 0 policies returned.
192 * @throws CoderException CoderException
195 public void test02NoPolicies() throws CoderException {
197 // Ask for a decision when there are no policies loaded
199 LOGGER.info("Request {}", gson.encode(baseRequest));
200 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
201 LOGGER.info("Decision {}", decision.getKey());
203 assertThat(decision.getKey()).isNotNull();
204 assertThat(decision.getKey().getPolicies().size()).isEqualTo(0);
208 * Should return ONLY default policies.
210 * @throws XacmlApplicationException could not load policies
213 public void test03OptimizationDefault() throws XacmlApplicationException {
215 // Now load all the optimization policies
217 TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service);
219 // Ask for a decision for available default policies
221 DecisionResponse response = makeDecision();
223 assertThat(response).isNotNull();
224 assertThat(response.getPolicies().size()).isEqualTo(2);
228 validateDecision(response, baseRequest);
232 * Should only return default HPA policy type.
234 @SuppressWarnings("unchecked")
236 public void test04OptimizationDefaultHpa() {
238 // Add in policy type
240 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.resource.HpaPolicy");
241 baseRequest.getResource().put("policy-type", policyTypes);
243 // Ask for a decision for default HPA policy
245 DecisionResponse response = makeDecision();
247 assertThat(response).isNotNull();
248 assertThat(response.getPolicies().size()).isEqualTo(1);
249 response.getPolicies().forEach((key, value) -> {
250 assertThat(((Map<String, Object>) value).get("type"))
251 .isEqualTo(("onap.policies.optimization.resource.HpaPolicy"));
256 validateDecision(response, baseRequest);
260 * Refine for US only policies.
262 @SuppressWarnings("unchecked")
264 public void test05OptimizationDefaultGeography() throws CoderException {
266 // Remove all the policy-type resources from the request
270 // Add US to the geography list
272 ((List<String>)baseRequest.getResource().get("geography")).add("US");
274 // Ask for a decision for default US Policy
276 DecisionResponse response = makeDecision();
277 assertThat(response).isNotNull();
278 assertThat(response.getPolicies().size()).isEqualTo(2);
282 validateDecision(response, baseRequest);
286 * Add more refinement for service.
288 @SuppressWarnings("unchecked")
290 public void test06OptimizationDefaultGeographyAndService() {
292 // Add vCPE to the service list
294 ((List<String>)baseRequest.getResource().get("services")).add("vCPE");
296 // Ask for a decision for default US policy for vCPE service
298 DecisionResponse response = makeDecision();
300 assertThat(response).isNotNull();
301 assertThat(response.getPolicies().size()).isEqualTo(3);
305 validateDecision(response, baseRequest);
309 * Add more refinement for specific resource.
311 @SuppressWarnings("unchecked")
313 public void test07OptimizationDefaultGeographyAndServiceAndResource() {
315 // Add vG to the resource list
317 ((List<String>)baseRequest.getResource().get("resources")).add("vG");
319 // Ask for a decision for default US service vCPE resource vG policy
321 DecisionResponse response = makeDecision();
323 assertThat(response).isNotNull();
324 assertThat(response.getPolicies().size()).isEqualTo(6);
328 validateDecision(response, baseRequest);
332 * Now we need to add in subscriberName in order to get scope for gold.
334 @SuppressWarnings("unchecked")
336 public void test08OptimizationGeographyAndServiceAndResourceAndScopeIsGoldSubscriber() {
338 // Add gold as a scope
340 //((List<String>)baseRequest.getResource().get("scope")).add("gold");
341 ((List<String>)baseRequest.getContext().get("subscriberName")).add("subscriber_a");
343 // Ask for a decision for specific US vCPE vG gold
345 DecisionResponse response = makeDecision();
347 assertThat(response).isNotNull();
348 assertThat(response.getPolicies().size()).isEqualTo(6);
352 validateDecision(response, baseRequest);
356 * Add a subscriber that should be platinum.
358 @SuppressWarnings("unchecked")
360 public void test09OptimizationGeographyAndServiceAndResourceAndScopeGoldOrPlatinumSubscriber() {
362 // Add platinum to the scope list: this is now gold OR platinum
364 ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
365 ((List<String>)baseRequest.getContext().get("subscriberName")).add("subscriber_x");
367 // Ask for a decision for specific US vCPE vG (gold or platinum)
369 DecisionResponse response = makeDecision();
371 assertThat(response).isNotNull();
372 assertThat(response.getPolicies().size()).isEqualTo(8);
376 validateDecision(response, baseRequest);
380 * Remove gold subscriber, keep the platinum one.
382 @SuppressWarnings("unchecked")
384 public void test10OptimizationGeographyAndServiceAndResourceAndScopeNotGoldStillPlatinum() {
386 // Add gold as a scope
388 ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
389 ((List<String>)baseRequest.getResource().get("scope")).remove("platinum");
390 ((List<String>)baseRequest.getContext().get("subscriberName")).remove("subscriber_a");
392 // Ask for a decision for specific US vCPE vG gold
394 DecisionResponse response = makeDecision();
396 assertThat(response).isNotNull();
397 assertThat(response.getPolicies().size()).isEqualTo(7);
401 validateDecision(response, baseRequest);
405 * Filter by Affinity policy.
408 public void test11OptimizationPolicyTypeDefault() {
410 // Add in policy type
412 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.resource.AffinityPolicy");
413 baseRequest.getResource().put("policy-type", policyTypes);
415 // Ask for a decision for default
417 DecisionResponse response = makeDecision();
419 assertThat(response).isNotNull();
420 assertThat(response.getPolicies().size()).isEqualTo(1);
424 validateDecision(response, baseRequest);
428 * Now filter by HPA policy type.
430 @SuppressWarnings("unchecked")
432 public void test12OptimizationPolicyTypeDefault() {
434 // Add in another policy type
436 ((List<String>) baseRequest.getResource().get("policy-type"))
437 .add("onap.policies.optimization.resource.HpaPolicy");
439 // Ask for a decision for default
441 DecisionResponse response = makeDecision();
443 assertThat(response).isNotNull();
444 assertThat(response.getPolicies().size()).isEqualTo(2);
448 validateDecision(response, baseRequest);
451 private DecisionResponse makeDecision() {
452 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
453 LOGGER.info("Request Resources {}", baseRequest.getResource());
454 LOGGER.info("Decision {}", decision.getKey());
455 for (Entry<String, Object> entrySet : decision.getKey().getPolicies().entrySet()) {
456 LOGGER.info("Policy {}", entrySet.getKey());
458 return decision.getKey();
461 @SuppressWarnings("unchecked")
462 private void validateDecision(DecisionResponse decision, DecisionRequest request) {
463 for (Entry<String, Object> entrySet : decision.getPolicies().entrySet()) {
464 LOGGER.info("Decision Returned Policy {}", entrySet.getKey());
465 assertThat(entrySet.getValue()).isInstanceOf(Map.class);
466 Map<String, Object> policyContents = (Map<String, Object>) entrySet.getValue();
467 assertThat(policyContents.containsKey("properties")).isTrue();
468 assertThat(policyContents.get("properties")).isInstanceOf(Map.class);
469 Map<String, Object> policyProperties = (Map<String, Object>) policyContents.get("properties");
471 validateMatchable((Collection<String>) request.getResource().get("scope"),
472 (Collection<String>) policyProperties.get("scope"));
474 validateMatchable((Collection<String>) request.getResource().get("services"),
475 (Collection<String>) policyProperties.get("services"));
477 validateMatchable((Collection<String>) request.getResource().get("resources"),
478 (Collection<String>) policyProperties.get("resources"));
480 validateMatchable((Collection<String>) request.getResource().get("geography"),
481 (Collection<String>) policyProperties.get("geography"));
485 private void validateMatchable(Collection<String> requestList, Collection<String> policyProperties) {
486 LOGGER.info("Validating matchable: {} with {}", policyProperties, requestList);
488 // Null or empty implies '*' - that is any value is acceptable
491 if (policyProperties == null || policyProperties.isEmpty()) {
494 Condition<String> condition = new Condition<>(
495 requestList::contains,
496 "Request list is contained");
497 assertThat(policyProperties).haveAtLeast(1, condition);
501 @SuppressWarnings("unchecked")
502 private void cleanOutResources() {
503 ((List<String>)baseRequest.getResource().get("scope")).clear();
504 ((List<String>)baseRequest.getResource().get("services")).clear();
505 ((List<String>)baseRequest.getResource().get("resources")).clear();
506 ((List<String>)baseRequest.getResource().get("geography")).clear();
507 if (((List<String>)baseRequest.getResource().get("policy-type")) != null) {
508 baseRequest.getResource().remove("policy-type");