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.io.FileNotFoundException;
34 import java.io.IOException;
35 import java.nio.file.Files;
36 import java.nio.file.Paths;
37 import java.util.Collection;
38 import java.util.Iterator;
39 import java.util.List;
41 import java.util.Map.Entry;
42 import java.util.Properties;
43 import java.util.ServiceLoader;
44 import org.apache.commons.lang3.tuple.Pair;
45 import org.assertj.core.api.Condition;
46 import org.junit.BeforeClass;
47 import org.junit.ClassRule;
48 import org.junit.FixMethodOrder;
49 import org.junit.Test;
50 import org.junit.rules.TemporaryFolder;
51 import org.junit.runners.MethodSorters;
52 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
53 import org.onap.policy.common.utils.coder.CoderException;
54 import org.onap.policy.common.utils.coder.StandardCoder;
55 import org.onap.policy.common.utils.resources.ResourceUtils;
56 import org.onap.policy.common.utils.resources.TextFileUtils;
57 import org.onap.policy.models.decisions.concepts.DecisionRequest;
58 import org.onap.policy.models.decisions.concepts.DecisionResponse;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
60 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
61 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
62 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
63 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
68 public class OptimizationPdpApplicationTest {
70 private static final Logger LOGGER = LoggerFactory.getLogger(OptimizationPdpApplicationTest.class);
71 private static Properties properties = new Properties();
72 private static File propertiesFile;
73 private static XacmlApplicationServiceProvider service;
74 private static StandardCoder gson = new StandardCoder();
75 private static DecisionRequest baseRequest;
76 private static RestServerParameters clientParams;
77 private static String[] listPolicyTypeFiles = {
78 "onap.policies.Optimization",
79 "onap.policies.optimization.Resource",
80 "onap.policies.optimization.Service",
81 "onap.policies.optimization.resource.AffinityPolicy",
82 "onap.policies.optimization.resource.DistancePolicy",
83 "onap.policies.optimization.resource.HpaPolicy",
84 "onap.policies.optimization.resource.OptimizationPolicy",
85 "onap.policies.optimization.resource.PciPolicy",
86 "onap.policies.optimization.service.QueryPolicy",
87 "onap.policies.optimization.service.SubscriberPolicy",
88 "onap.policies.optimization.resource.Vim_fit",
89 "onap.policies.optimization.resource.VnfPolicy"};
92 public static final TemporaryFolder policyFolder = new TemporaryFolder();
95 * Copies the xacml.properties and policies files into
96 * temporary folder and loads the service provider saving
97 * instance of provider off for other tests to use.
100 public static void setUp() throws Exception {
101 clientParams = mock(RestServerParameters.class);
102 when(clientParams.getHost()).thenReturn("localhost");
103 when(clientParams.getPort()).thenReturn(6969);
105 // Load Single Decision Request
107 baseRequest = gson.decode(
109 .getTextFileAsString(
110 "src/test/resources/decision.optimization.input.json"),
111 DecisionRequest.class);
113 // Setup our temporary folder
115 XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
116 propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
117 properties, myCreator);
119 // Copy the test policy types into data area
121 for (String policy : listPolicyTypeFiles) {
122 String policyType = ResourceUtils.getResourceAsString("policytypes/" + policy + ".yaml");
123 LOGGER.info("Copying {}", policyType);
124 Files.write(Paths.get(policyFolder.getRoot().getAbsolutePath(), policy + "-1.0.0.yaml"),
125 policyType.getBytes());
130 ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
131 ServiceLoader.load(XacmlApplicationServiceProvider.class);
133 // Iterate through Xacml application services and find
134 // the optimization service. Save it for use throughout
135 // all the Junit tests.
137 StringBuilder strDump = new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
138 Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
139 while (iterator.hasNext()) {
140 XacmlApplicationServiceProvider application = iterator.next();
142 // Is it our service?
144 if (application instanceof OptimizationPdpApplication) {
146 // Should be the first and only one
148 assertThat(service).isNull();
149 service = application;
151 strDump.append(application.applicationName());
152 strDump.append(" supports ");
153 strDump.append(application.supportedPolicyTypes());
154 strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
156 LOGGER.debug("{}", strDump);
157 assertThat(service).isNotNull();
159 // Tell it to initialize based on the properties file
160 // we just built for it.
162 service.initialize(propertiesFile.toPath().getParent(), clientParams);
166 public void test01Basics() {
168 // Make sure there's an application name
170 assertThat(service.applicationName()).isNotEmpty();
174 assertThat(service.actionDecisionsSupported().size()).isEqualTo(1);
175 assertThat(service.actionDecisionsSupported()).contains("optimize");
177 // Ensure it has the supported policy types and
178 // can support the correct policy types.
180 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
181 "onap.policies.optimization.resource.AffinityPolicy", "1.0.0"))).isTrue();
182 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
183 "onap.policies.optimization.service.SubscriberPolicy", "1.0.0"))).isTrue();
184 assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
185 "onap.foobar", "1.0.0"))).isFalse();
189 public void test02NoPolicies() throws CoderException {
191 // Ask for a decision when there are no policies loaded
193 LOGGER.info("Request {}", gson.encode(baseRequest));
194 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
195 LOGGER.info("Decision {}", decision.getKey());
197 assertThat(decision.getKey()).isNotNull();
198 assertThat(decision.getKey().getPolicies().size()).isEqualTo(0);
202 public void test03OptimizationDefault() throws CoderException, FileNotFoundException, IOException,
203 XacmlApplicationException {
205 // Now load all the optimization policies
207 TestUtils.loadPolicies("src/test/resources/vCPE.policies.optimization.input.tosca.yaml", service);
209 // Ask for a decision for available default policies
211 DecisionResponse response = makeDecision();
213 assertThat(response).isNotNull();
214 assertThat(response.getPolicies().size()).isEqualTo(2);
218 validateDecision(response, baseRequest);
221 @SuppressWarnings("unchecked")
223 public void test04OptimizationDefaultHpa() throws CoderException, FileNotFoundException, IOException,
224 XacmlApplicationException {
226 // Add in policy type
228 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.resource.HpaPolicy");
229 baseRequest.getResource().put("policy-type", policyTypes);
231 // Ask for a decision for default HPA policy
233 DecisionResponse response = makeDecision();
235 assertThat(response).isNotNull();
236 assertThat(response.getPolicies().size()).isEqualTo(1);
237 response.getPolicies().forEach((key, value) -> {
238 assertThat(((Map<String, Object>) value).get("type"))
239 .isEqualTo(("onap.policies.optimization.resource.HpaPolicy"));
244 validateDecision(response, baseRequest);
247 @SuppressWarnings("unchecked")
249 public void test05OptimizationDefaultGeography() throws CoderException {
251 // Remove all the policy-type resources from the request
255 // Add US to the geography list
257 ((List<String>)baseRequest.getResource().get("geography")).add("US");
259 // Ask for a decision for default US Policy
261 DecisionResponse response = makeDecision();
262 assertThat(response).isNotNull();
263 assertThat(response.getPolicies().size()).isEqualTo(2);
267 validateDecision(response, baseRequest);
270 @SuppressWarnings("unchecked")
272 public void test06OptimizationDefaultGeographyAndService() throws CoderException {
274 // Add vCPE to the service list
276 ((List<String>)baseRequest.getResource().get("services")).add("vCPE");
278 // Ask for a decision for default US policy for vCPE service
280 DecisionResponse response = makeDecision();
282 assertThat(response).isNotNull();
283 assertThat(response.getPolicies().size()).isEqualTo(5);
287 validateDecision(response, baseRequest);
290 @SuppressWarnings("unchecked")
292 public void test07OptimizationDefaultGeographyAndServiceAndResource() throws CoderException {
294 // Add vG to the resource list
296 ((List<String>)baseRequest.getResource().get("resources")).add("vG");
298 // Ask for a decision for default US service vCPE resource vG policy
300 DecisionResponse response = makeDecision();
302 assertThat(response).isNotNull();
303 assertThat(response.getPolicies().size()).isEqualTo(8);
307 validateDecision(response, baseRequest);
310 @SuppressWarnings("unchecked")
312 public void test08OptimizationGeographyAndServiceAndResourceAndScope() throws CoderException {
314 // Add gold as a scope
316 ((List<String>)baseRequest.getResource().get("scope")).add("gold");
318 // Ask for a decision for specific US vCPE vG gold
320 DecisionResponse response = makeDecision();
322 assertThat(response).isNotNull();
323 assertThat(response.getPolicies().size()).isEqualTo(8);
327 validateDecision(response, baseRequest);
330 @SuppressWarnings("unchecked")
332 public void test09OptimizationGeographyAndServiceAndResourceAndScopeIsGoldOrPlatinum() throws CoderException {
334 // Add platinum to the scope list: this is now gold OR platinum
336 ((List<String>)baseRequest.getResource().get("scope")).add("platinum");
338 // Ask for a decision for specific US vCPE vG (gold or platinum)
340 DecisionResponse response = makeDecision();
342 assertThat(response).isNotNull();
343 assertThat(response.getPolicies().size()).isEqualTo(10);
347 validateDecision(response, baseRequest);
350 @SuppressWarnings("unchecked")
352 public void test10OptimizationGeographyAndServiceAndResourceAndScopeNotGold() throws CoderException {
354 // Add gold as a scope
356 ((List<String>)baseRequest.getResource().get("scope")).remove("gold");
358 // Ask for a decision for specific US vCPE vG gold
360 DecisionResponse response = makeDecision();
362 assertThat(response).isNotNull();
363 assertThat(response.getPolicies().size()).isEqualTo(9);
367 validateDecision(response, baseRequest);
371 public void test11OptimizationPolicyTypeDefault() throws CoderException {
373 // Add in policy type
375 List<String> policyTypes = Lists.newArrayList("onap.policies.optimization.resource.AffinityPolicy");
376 baseRequest.getResource().put("policy-type", policyTypes);
378 // Ask for a decision for default
380 DecisionResponse response = makeDecision();
382 assertThat(response).isNotNull();
383 assertThat(response.getPolicies().size()).isEqualTo(1);
387 validateDecision(response, baseRequest);
390 @SuppressWarnings("unchecked")
392 public void test12OptimizationPolicyTypeDefault() throws CoderException {
394 // Add in another policy type
396 ((List<String>) baseRequest.getResource().get("policy-type"))
397 .add("onap.policies.optimization.resource.HpaPolicy");
399 // Ask for a decision for default
401 DecisionResponse response = makeDecision();
403 assertThat(response).isNotNull();
404 assertThat(response.getPolicies().size()).isEqualTo(2);
408 validateDecision(response, baseRequest);
411 private DecisionResponse makeDecision() {
412 Pair<DecisionResponse, Response> decision = service.makeDecision(baseRequest, null);
413 LOGGER.info("Request Resources {}", baseRequest.getResource());
414 LOGGER.info("Decision {}", decision.getKey());
415 for (Entry<String, Object> entrySet : decision.getKey().getPolicies().entrySet()) {
416 LOGGER.info("Policy {}", entrySet.getKey());
418 return decision.getKey();
421 @SuppressWarnings("unchecked")
422 private void validateDecision(DecisionResponse decision, DecisionRequest request) {
423 for (Entry<String, Object> entrySet : decision.getPolicies().entrySet()) {
424 LOGGER.info("Decision Returned Policy {}", entrySet.getKey());
425 assertThat(entrySet.getValue()).isInstanceOf(Map.class);
426 Map<String, Object> policyContents = (Map<String, Object>) entrySet.getValue();
427 assertThat(policyContents.containsKey("properties")).isTrue();
428 assertThat(policyContents.get("properties")).isInstanceOf(Map.class);
429 Map<String, Object> policyProperties = (Map<String, Object>) policyContents.get("properties");
431 validateMatchable((Collection<String>) request.getResource().get("scope"),
432 (Collection<String>) policyProperties.get("scope"));
434 validateMatchable((Collection<String>) request.getResource().get("services"),
435 (Collection<String>) policyProperties.get("services"));
437 validateMatchable((Collection<String>) request.getResource().get("resources"),
438 (Collection<String>) policyProperties.get("resources"));
440 validateMatchable((Collection<String>) request.getResource().get("geography"),
441 (Collection<String>) policyProperties.get("geography"));
445 private void validateMatchable(Collection<String> requestList, Collection<String> policyProperties) {
446 LOGGER.info("Validating matchable: {} with {}", policyProperties, requestList);
448 // Null or empty implies '*' - that is any value is acceptable
451 if (policyProperties == null || policyProperties.isEmpty()) {
454 Condition<String> condition = new Condition<>(
455 requestList::contains,
456 "Request list is contained");
457 assertThat(policyProperties).haveAtLeast(1, condition);
461 @SuppressWarnings("unchecked")
462 private void cleanOutResources() {
463 ((List<String>)baseRequest.getResource().get("scope")).clear();
464 ((List<String>)baseRequest.getResource().get("services")).clear();
465 ((List<String>)baseRequest.getResource().get("resources")).clear();
466 ((List<String>)baseRequest.getResource().get("geography")).clear();
467 if (((List<String>)baseRequest.getResource().get("policy-type")) != null) {
468 baseRequest.getResource().remove("policy-type");