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;
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;
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;
68 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
69 public class OptimizationPdpApplicationTest {
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"};
91 public static final TemporaryFolder policyFolder = new TemporaryFolder();
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.
99 public static void setUp() throws Exception {
100 clientParams = mock(RestServerParameters.class);
101 when(clientParams.getHost()).thenReturn("localhost");
102 when(clientParams.getPort()).thenReturn(6969);
104 // Load Single Decision Request
106 baseRequest = gson.decode(
108 .getTextFileAsString(
109 "src/test/resources/decision.optimization.input.json"),
110 DecisionRequest.class);
112 // Setup our temporary folder
114 XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
115 propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
116 properties, myCreator);
118 // Copy the test policy types into data area
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());
129 ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
130 ServiceLoader.load(XacmlApplicationServiceProvider.class);
132 // Iterate through Xacml application services and find
133 // the optimization service. Save it for use throughout
134 // all the Junit tests.
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();
141 // Is it our service?
143 if (application instanceof OptimizationPdpApplication) {
145 // Should be the first and only one
147 assertThat(service).isNull();
148 service = application;
150 strDump.append(application.applicationName());
151 strDump.append(" supports ");
152 strDump.append(application.supportedPolicyTypes());
153 strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
155 LOGGER.debug("{}", strDump);
156 assertThat(service).isNotNull();
158 // Tell it to initialize based on the properties file
159 // we just built for it.
161 service.initialize(propertiesFile.toPath().getParent(), clientParams);
165 public void test01Basics() {
167 // Make sure there's an application name
169 assertThat(service.applicationName()).isNotEmpty();
173 assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
174 assertThat(service.actionDecisionsSupported()).contains("optimize");
176 // Ensure it has the supported policy types and
177 // can support the correct policy types.
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();
186 public void test02NoPolicies() {
188 // Ask for a decision when there are no policies loaded
190 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
191 LOGGER.info("Decision {}", decision.getKey());
193 assertThat(decision.getKey()).isNotNull();
194 assertThat(decision.getKey().getPolicies().size()).isEqualTo(0);
198 public void test03OptimizationDefault() throws CoderException, FileNotFoundException, IOException,
199 XacmlApplicationException {
201 // Now load all the optimization policies
203 TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service);
205 // Ask for a decision for default
207 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
208 LOGGER.info("Decision {}", decision.getKey());
210 assertThat(decision.getKey()).isNotNull();
211 assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
213 // Double check that the contents are what we expect
215 LOGGER.info(gson.encode(decision.getKey()));
219 validateDecision(decision.getKey(), baseRequest);
222 @SuppressWarnings("unchecked")
224 public void test04OptimizationDefaultGeography() throws CoderException {
226 // Add US to the geography list
228 ((List<String>)baseRequest.getResource().get("geography")).add("US");
230 // Ask for a decision for default US Policy
232 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
233 LOGGER.info("Decision {}", decision.getKey());
235 assertThat(decision.getKey()).isNotNull();
236 assertThat(decision.getKey().getPolicies().size()).isEqualTo(2);
238 // Double check that the contents are what we expect
240 LOGGER.info(gson.encode(decision.getKey()));
244 validateDecision(decision.getKey(), baseRequest);
247 @SuppressWarnings("unchecked")
249 public void test05OptimizationDefaultGeographyAndService() throws CoderException {
251 // Add vCPE to the service list
253 ((List<String>)baseRequest.getResource().get("services")).add("vCPE");
255 // Ask for a decision for default US policy for vCPE service
257 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
258 LOGGER.info("Decision {}", decision.getKey());
260 assertThat(decision.getKey()).isNotNull();
261 assertThat(decision.getKey().getPolicies().size()).isEqualTo(5);
263 // Double check that the contents are what we expect
265 LOGGER.info(gson.encode(decision.getKey()));
269 validateDecision(decision.getKey(), baseRequest);
272 @SuppressWarnings("unchecked")
274 public void test06OptimizationDefaultGeographyAndServiceAndResource() throws CoderException {
276 // Add vCPE to the service list
278 ((List<String>)baseRequest.getResource().get("resources")).add("vG");
280 // Ask for a decision for default US service vCPE resource vG policy
282 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
283 LOGGER.info("Decision {}", decision.getKey());
285 assertThat(decision.getKey()).isNotNull();
286 assertThat(decision.getKey().getPolicies().size()).isEqualTo(9);
288 // Double check that the contents are what we expect
290 LOGGER.info(gson.encode(decision.getKey()));
294 validateDecision(decision.getKey(), baseRequest);
297 @SuppressWarnings("unchecked")
299 public void test07OptimizationGeographyAndServiceAndResourceAndScope() throws CoderException {
301 // Add gold as a scope
303 ((List<String>)baseRequest.getResource().get("scope")).add("gold");
305 // Ask for a decision for specific US vCPE vG gold
307 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
308 LOGGER.info("Decision {}", decision.getKey());
310 assertThat(decision.getKey()).isNotNull();
311 assertThat(decision.getKey().getPolicies().size()).isEqualTo(10);
313 // Double check that the contents are what we expect
315 LOGGER.info(gson.encode(decision.getKey()));
319 validateDecision(decision.getKey(), baseRequest);
322 @SuppressWarnings("unchecked")
324 public void test08OptimizationGeographyAndServiceAndResourceAndScopeIsGoldOrPlatinum() throws CoderException {
326 // Add platinum to the scope list: this is now gold OR platinum
328 ((List<String>)baseRequest.getResource().get("scope")).add("platinum");
330 // Ask for a decision for specific US vCPE vG (gold or platinum)
332 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
333 LOGGER.info("Decision {}", decision.getKey());
335 assertThat(decision.getKey()).isNotNull();
336 assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
338 // Double check that the contents are what we expect
340 LOGGER.info(gson.encode(decision.getKey()));
344 validateDecision(decision.getKey(), baseRequest);
347 @SuppressWarnings("unchecked")
349 public void test09OptimizationGeographyAndServiceAndResourceAndScopeNotGold() throws CoderException {
351 // Add gold as a scope
353 ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
355 // Ask for a decision for specific US vCPE vG gold
357 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
358 LOGGER.info("Decision {}", decision.getKey());
360 assertThat(decision.getKey()).isNotNull();
361 assertThat(decision.getKey().getPolicies().size()).isEqualTo(11);
363 // Double check that the contents are what we expect
365 LOGGER.info(gson.encode(decision.getKey()));
369 validateDecision(decision.getKey(), baseRequest);
373 public void test10OptimizationPolicyTypeDefault() throws CoderException {
375 // Remove all the other resources from the request
379 // Add in policy type
381 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.AffinityPolicy");
382 baseRequest.getResource().put("policy-type", policyTypes);
384 // Ask for a decision for default
386 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
387 LOGGER.info("Decision {}", decision.getKey());
389 assertThat(decision.getKey()).isNotNull();
390 assertThat(decision.getKey().getPolicies().size()).isEqualTo(4);
392 // Double check that the contents are what we expect
394 LOGGER.info(gson.encode(decision.getKey()));
398 public void test20OptimizationPolicyTypeDefault() throws CoderException {
400 // Remove all the other resources from the request
404 // Add in policy type
406 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.HpaPolicy");
407 baseRequest.getResource().put("policy-type", policyTypes);
409 // Ask for a decision for default
411 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
412 LOGGER.info("Decision {}", decision.getKey());
414 assertThat(decision.getKey()).isNotNull();
415 assertThat(decision.getKey().getPolicies().size()).isEqualTo(1);
417 // Double check that the contents are what we expect
419 LOGGER.info(gson.encode(decision.getKey()));
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");
432 validateMatchable((Collection<String>) request.getResource().get("scope"),
433 (Collection<String>) policyProperties.get("scope"));
435 validateMatchable((Collection<String>) request.getResource().get("services"),
436 (Collection<String>) policyProperties.get("services"));
438 validateMatchable((Collection<String>) request.getResource().get("resources"),
439 (Collection<String>) policyProperties.get("resources"));
441 validateMatchable((Collection<String>) request.getResource().get("geography"),
442 (Collection<String>) policyProperties.get("geography"));
446 private void validateMatchable(Collection<String> requestList, Collection<String> policyProperties) {
447 LOGGER.info("Validating matchable: {} with {}", policyProperties, requestList);
449 // Null or empty implies '*' - that is any value is acceptable
452 if (policyProperties == null || policyProperties.isEmpty()) {
455 Condition<String> condition = new Condition<>(
456 requestList::contains,
457 "Request list is contained");
458 assertThat(policyProperties).haveAtLeast(1, condition);
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();