2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.xacml.pdp.application.optimization;
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.when;
29 import com.att.research.xacml.api.Response;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
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 jersey.repackaged.com.google.common.collect.Lists;
43 import org.apache.commons.lang3.tuple.Pair;
44 import org.assertj.core.api.Condition;
45 import org.junit.BeforeClass;
46 import org.junit.ClassRule;
47 import org.junit.FixMethodOrder;
48 import org.junit.Test;
49 import org.junit.rules.TemporaryFolder;
50 import org.junit.runners.MethodSorters;
51 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
52 import org.onap.policy.common.utils.coder.CoderException;
53 import org.onap.policy.common.utils.coder.StandardCoder;
54 import org.onap.policy.common.utils.resources.ResourceUtils;
55 import org.onap.policy.common.utils.resources.TextFileUtils;
56 import org.onap.policy.models.decisions.concepts.DecisionRequest;
57 import org.onap.policy.models.decisions.concepts.DecisionResponse;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
59 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
60 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
61 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
62 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
67 public class OptimizationPdpApplicationTest {
69 private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTest.class);
70 private static Properties properties = new Properties();
71 private static File propertiesFile;
72 private static XacmlApplicationServiceProvider service;
73 private static StandardCoder gson = new StandardCoder();
74 private static DecisionRequest baseRequest;
75 private static RestServerParameters clientParams;
76 private static String[] listPolicyTypeFiles = {
77 "onap.policies.Optimization",
78 "onap.policies.optimization.AffinityPolicy",
79 "onap.policies.optimization.DistancePolicy",
80 "onap.policies.optimization.HpaPolicy",
81 "onap.policies.optimization.OptimizationPolicy",
82 "onap.policies.optimization.PciPolicy",
83 "onap.policies.optimization.QueryPolicy",
84 "onap.policies.optimization.SubscriberPolicy",
85 "onap.policies.optimization.Vim_fit",
86 "onap.policies.optimization.VnfPolicy"};
89 public static final TemporaryFolder policyFolder = new TemporaryFolder();
92 * Copies the xacml.properties and policies files into
93 * temporary folder and loads the service provider saving
94 * instance of provider off for other tests to use.
97 public static void setUp() throws Exception {
98 clientParams = mock(RestServerParameters.class);
99 when(clientParams.getHost()).thenReturn("localhost");
100 when(clientParams.getPort()).thenReturn(6969);
102 // Load Single Decision Request
104 baseRequest = gson.decode(
106 .getTextFileAsString(
107 "src/test/resources/decision.optimization.input.json"),
108 DecisionRequest.class);
110 // Setup our temporary folder
112 XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
113 propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
114 properties, myCreator);
116 // Copy the test policy types into data area
118 for (String policy : listPolicyTypeFiles) {
119 String policyType = ResourceUtils.getResourceAsString("policytypes/" + policy + ".yaml");
120 LOGGER.info("Copying {}", policyType);
121 Files.write(Paths.get(policyFolder.getRoot().getAbsolutePath(), policy + "-1.0.0.yaml"),
122 policyType.getBytes());
127 ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
128 ServiceLoader.load(XacmlApplicationServiceProvider.class);
130 // Iterate through Xacml application services and find
131 // the optimization service. Save it for use throughout
132 // all the Junit tests.
134 StringBuilder strDump = new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
135 Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
136 while (iterator.hasNext()) {
137 XacmlApplicationServiceProvider application = iterator.next();
139 // Is it our service?
141 if (application instanceof OptimizationPdpApplication) {
143 // Should be the first and only one
145 assertThat(service).isNull();
146 service = application;
148 strDump.append(application.applicationName());
149 strDump.append(" supports ");
150 strDump.append(application.supportedPolicyTypes());
151 strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
153 LOGGER.debug("{}", strDump);
154 assertThat(service).isNotNull();
156 // Tell it to initialize based on the properties file
157 // we just built for it.
159 service.initialize(propertiesFile.toPath().getParent(), clientParams);
163 public void test01Basics() {
165 // Make sure there's an application name
167 assertThat(service.applicationName()).isNotEmpty();
171 assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
172 assertThat(service.actionDecisionsSupported()).contains("optimize");
174 // Ensure it has the supported policy types and
175 // can support the correct policy types.
177 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
178 "onap.policies.optimization.AffinityPolicy", "1.0.0"))).isTrue();
179 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
180 "onap.foobar", "1.0.0"))).isFalse();
184 public void test02NoPolicies() {
186 // Ask for a decision when there are no policies loaded
188 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
189 LOGGER.info("Decision {}", decision.getKey());
191 assertThat(decision.getKey()).isNotNull();
192 assertThat(decision.getKey().getPolicies().size()).isEqualTo(0);
196 public void test03OptimizationDefault() throws CoderException, FileNotFoundException, IOException,
197 XacmlApplicationException {
199 // Now load all the optimization policies
201 TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service);
203 // Ask for a decision for default
205 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
206 LOGGER.info("Decision {}", decision.getKey());
208 assertThat(decision.getKey()).isNotNull();
209 assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
211 // Double check that the contents are what we expect
213 LOGGER.info(gson.encode(decision.getKey()));
217 validateDecision(decision.getKey(), baseRequest);
220 @SuppressWarnings("unchecked")
222 public void test04OptimizationDefaultGeography() throws CoderException {
224 // Add US to the geography list
226 ((List<String>)baseRequest.getResource().get("geography")).add("US");
228 // Ask for a decision for default US Policy
230 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
231 LOGGER.info("Decision {}", decision.getKey());
233 assertThat(decision.getKey()).isNotNull();
234 assertThat(decision.getKey().getPolicies().size()).isEqualTo(2);
236 // Double check that the contents are what we expect
238 LOGGER.info(gson.encode(decision.getKey()));
242 validateDecision(decision.getKey(), baseRequest);
245 @SuppressWarnings("unchecked")
247 public void test05OptimizationDefaultGeographyAndService() throws CoderException {
249 // Add vCPE to the service list
251 ((List<String>)baseRequest.getResource().get("services")).add("vCPE");
253 // Ask for a decision for default US policy for vCPE service
255 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
256 LOGGER.info("Decision {}", decision.getKey());
258 assertThat(decision.getKey()).isNotNull();
259 assertThat(decision.getKey().getPolicies().size()).isEqualTo(5);
261 // Double check that the contents are what we expect
263 LOGGER.info(gson.encode(decision.getKey()));
267 validateDecision(decision.getKey(), baseRequest);
270 @SuppressWarnings("unchecked")
272 public void test06OptimizationDefaultGeographyAndServiceAndResource() throws CoderException {
274 // Add vCPE to the service list
276 ((List<String>)baseRequest.getResource().get("resources")).add("vG");
278 // Ask for a decision for default US service vCPE resource vG policy
280 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
281 LOGGER.info("Decision {}", decision.getKey());
283 assertThat(decision.getKey()).isNotNull();
284 assertThat(decision.getKey().getPolicies().size()).isEqualTo(9);
286 // Double check that the contents are what we expect
288 LOGGER.info(gson.encode(decision.getKey()));
292 validateDecision(decision.getKey(), baseRequest);
295 @SuppressWarnings("unchecked")
297 public void test07OptimizationGeographyAndServiceAndResourceAndScope() throws CoderException {
299 // Add gold as a scope
301 ((List<String>)baseRequest.getResource().get("scope")).add("gold");
303 // Ask for a decision for specific US vCPE vG gold
305 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
306 LOGGER.info("Decision {}", decision.getKey());
308 assertThat(decision.getKey()).isNotNull();
309 assertThat(decision.getKey().getPolicies().size()).isEqualTo(10);
311 // Double check that the contents are what we expect
313 LOGGER.info(gson.encode(decision.getKey()));
317 validateDecision(decision.getKey(), baseRequest);
320 @SuppressWarnings("unchecked")
322 public void test08OptimizationGeographyAndServiceAndResourceAndScopeIsGoldOrPlatinum() throws CoderException {
324 // Add platinum to the scope list: this is now gold OR platinum
326 ((List<String>)baseRequest.getResource().get("scope")).add("platinum");
328 // Ask for a decision for specific US vCPE vG (gold or platinum)
330 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
331 LOGGER.info("Decision {}", decision.getKey());
333 assertThat(decision.getKey()).isNotNull();
334 assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
336 // Double check that the contents are what we expect
338 LOGGER.info(gson.encode(decision.getKey()));
342 validateDecision(decision.getKey(), baseRequest);
345 @SuppressWarnings("unchecked")
347 public void test09OptimizationGeographyAndServiceAndResourceAndScopeNotGold() throws CoderException {
349 // Add gold as a scope
351 ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
353 // Ask for a decision for specific US vCPE vG gold
355 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
356 LOGGER.info("Decision {}", decision.getKey());
358 assertThat(decision.getKey()).isNotNull();
359 assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
361 // Double check that the contents are what we expect
363 LOGGER.info(gson.encode(decision.getKey()));
367 validateDecision(decision.getKey(), baseRequest);
371 public void test10OptimizationPolicyTypeDefault() throws CoderException {
373 // Remove all the other resources from the request
377 // Add in policy type
379 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.AffinityPolicy");
380 baseRequest.getResource().put("policy-type", policyTypes);
382 // Ask for a decision for default
384 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
385 LOGGER.info("Decision {}", decision.getKey());
387 assertThat(decision.getKey()).isNotNull();
388 assertThat(decision.getKey().getPolicies().size()).isEqualTo(4);
390 // Double check that the contents are what we expect
392 LOGGER.info(gson.encode(decision.getKey()));
396 public void test20OptimizationPolicyTypeDefault() throws CoderException {
398 // Remove all the other resources from the request
402 // Add in policy type
404 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.HpaPolicy");
405 baseRequest.getResource().put("policy-type", policyTypes);
407 // Ask for a decision for default
409 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
410 LOGGER.info("Decision {}", decision.getKey());
412 assertThat(decision.getKey()).isNotNull();
413 assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
415 // Double check that the contents are what we expect
417 LOGGER.info(gson.encode(decision.getKey()));
420 @SuppressWarnings("unchecked")
421 private void validateDecision(DecisionResponse decision, DecisionRequest request) {
422 for (Entry<String, Object> entrySet : decision.getPolicies().entrySet()) {
423 LOGGER.info("Decision Returned Policy {}", entrySet.getKey());
424 assertThat(entrySet.getValue()).isInstanceOf(Map.class);
425 Map<String, Object> policyContents = (Map<String, Object>) entrySet.getValue();
426 assertThat(policyContents.containsKey("properties")).isTrue();
427 assertThat(policyContents.get("properties")).isInstanceOf(Map.class);
428 Map<String, Object> policyProperties = (Map<String, Object>) policyContents.get("properties");
430 validateMatchable((Collection<String>) request.getResource().get("scope"),
431 (Collection<String>) policyProperties.get("scope"));
433 validateMatchable((Collection<String>) request.getResource().get("services"),
434 (Collection<String>) policyProperties.get("services"));
436 validateMatchable((Collection<String>) request.getResource().get("resources"),
437 (Collection<String>) policyProperties.get("resources"));
439 validateMatchable((Collection<String>) request.getResource().get("geography"),
440 (Collection<String>) policyProperties.get("geography"));
444 private void validateMatchable(Collection<String> requestList, Collection<String> policyProperties) {
445 LOGGER.info("Validating matchable: {} with {}", policyProperties, requestList);
447 // Null or empty implies '*' - that is any value is acceptable
450 if (policyProperties == null || policyProperties.isEmpty()) {
453 Condition<String> condition = new Condition<>(
454 requestList::contains,
455 "Request list is contained");
456 assertThat(policyProperties).haveAtLeast(1, condition);
460 @SuppressWarnings("unchecked")
461 private void cleanOutResources() {
462 ((List<String>)baseRequest.getResource().get("scope")).clear();
463 ((List<String>)baseRequest.getResource().get("services")).clear();
464 ((List<String>)baseRequest.getResource().get("resources")).clear();
465 ((List<String>)baseRequest.getResource().get("geography")).clear();