2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 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.guard;
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
28 import com.att.research.xacml.api.Decision;
29 import com.att.research.xacml.api.Request;
30 import com.att.research.xacml.api.XACML3;
31 import com.att.research.xacml.std.StdMutableResponse;
32 import com.att.research.xacml.std.StdMutableResult;
33 import com.att.research.xacml.std.StdStatus;
34 import com.att.research.xacml.std.StdStatusCode;
35 import com.att.research.xacml.util.XACMLPolicyWriter;
36 import java.io.ByteArrayOutputStream;
37 import java.util.HashMap;
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
44 import org.junit.Test;
45 import org.onap.policy.common.utils.coder.StandardCoder;
46 import org.onap.policy.common.utils.coder.StandardYamlCoder;
47 import org.onap.policy.common.utils.resources.ResourceUtils;
48 import org.onap.policy.common.utils.resources.TextFileUtils;
49 import org.onap.policy.models.decisions.concepts.DecisionRequest;
50 import org.onap.policy.models.decisions.concepts.DecisionResponse;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
53 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
54 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
55 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 public class GuardTranslatorTest {
60 private static final Logger LOGGER = LoggerFactory.getLogger(GuardTranslatorTest.class);
61 private static final StandardYamlCoder yamlCoder = new StandardYamlCoder();
62 private static StandardCoder gson = new StandardCoder();
64 private GuardTranslator translator = new GuardTranslator();
67 public void testRequest() throws Exception {
68 DecisionRequest decisionRequest = gson.decode(
69 TextFileUtils.getTextFileAsString(
70 "src/test/resources/requests/guard.vfCount.json"),
71 DecisionRequest.class);
72 Request xacmlRequest = translator.convertRequest(decisionRequest);
74 assertThat(xacmlRequest).isNotNull();
78 public void testResponse() {
79 StdStatus status = new StdStatus(StdStatusCode.STATUS_CODE_OK);
80 StdMutableResult result = new StdMutableResult(Decision.PERMIT, status);
81 StdMutableResponse response = new StdMutableResponse(result);
83 DecisionResponse decisionResponse = translator.convertResponse(response);
84 assertThat(decisionResponse).isNotNull();
85 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
87 result = new StdMutableResult(Decision.DENY, status);
88 response = new StdMutableResponse(result);
89 decisionResponse = translator.convertResponse(response);
90 assertThat(decisionResponse).isNotNull();
91 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.DENY.toString());
93 result = new StdMutableResult(Decision.INDETERMINATE, status);
94 response = new StdMutableResponse(result);
95 decisionResponse = translator.convertResponse(response);
96 assertThat(decisionResponse).isNotNull();
97 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
102 public void testBadPolicies() throws Exception {
103 String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-bad-policies.yaml");
105 // Serialize it into a class
107 ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
109 // Make sure all the fields are setup properly
111 JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
112 jtst.fromAuthorative(serviceTemplate);
113 final ToscaServiceTemplate completedJtst = jtst.toAuthorative();
115 // Expected message for given policy name
117 final Map<String, String> name2message = new HashMap<>();
118 name2message.put("frequency-missing-properties", "Missing property limit");
119 name2message.put("frequency-timewindow", "timeWindow is not an integer");
120 name2message.put("minmax-notarget", "Missing target field in minmax policy");
121 name2message.put("minmax-nominmax", "Missing min or max field in minmax policy");
122 name2message.put("blacklist-noblacklist", "Missing blacklist");
123 name2message.put("filter-noalgorithm", "Missing algorithm");
124 name2message.put("filter-badalgorithm",
125 "Unexpected value for algorithm, should be whitelist-overrides or blacklist-overrides");
126 name2message.put("filter-nofilter", "Missing filters");
127 name2message.put("filter-nocollection", "Filters is not a collection");
128 name2message.put("filter-noarray", "Filters is not a collection");
129 name2message.put("filter-missingfield", "Missing \'field\' from filter");
130 name2message.put("filter-badfield", "Unexpected value for field in filter");
131 name2message.put("filter-missingfilter", "Missing \'filter\' from filter");
132 name2message.put("filter-missingfunction", "Missing \'function\' from filter");
133 name2message.put("filter-badfunction", "Unexpected value for function in filter");
134 name2message.put("filter-missingblacklist", "Missing \'blacklist\' from filter");
135 name2message.put("filter-badblacklist", "Unexpected value for blacklist in filter");
139 for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
140 for (ToscaPolicy policy : policies.values()) {
141 LOGGER.info("Testing policy " + policy.getName());
142 String expectedMsg = name2message.get(policy.getName());
143 assertThat(expectedMsg).as(policy.getName()).isNotNull();
145 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
146 translator.convertPolicy(policy)
147 ).withMessageContaining(expectedMsg);
153 public void testPolicyConversion() throws Exception {
154 String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-policies.yaml");
156 // Serialize it into a class
158 ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
160 // Make sure all the fields are setup properly
162 JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
163 jtst.fromAuthorative(serviceTemplate);
164 ToscaServiceTemplate completedJtst = jtst.toAuthorative();
168 for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
169 for (ToscaPolicy policy : policies.values()) {
171 // Convert the policy
173 if ("onap.policies.controlloop.guard.common.Unknown".equals(policy.getType())) {
174 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
175 translator.convertPolicy(policy));
178 PolicyType xacmlPolicy = (PolicyType) translator.convertPolicy(policy);
179 assertThat(xacmlPolicy).isNotNull();
183 ByteArrayOutputStream os = new ByteArrayOutputStream();
184 XACMLPolicyWriter.writePolicyFile(os, xacmlPolicy);
185 LOGGER.info(os.toString());
187 // Validate the policy
189 assertThat(xacmlPolicy.getPolicyId()).isEqualTo(policy.getName());
190 assertThat(xacmlPolicy.getVersion()).isEqualTo(policy.getVersion());
191 assertThat(xacmlPolicy.getRuleCombiningAlgId()).isNotNull();
192 validateCommon(policy, xacmlPolicy);
194 // Validate each policy type
196 if (GuardTranslator.POLICYTYPE_FREQUENCY.equals(policy.getType())) {
197 validateFrequency(policy, xacmlPolicy);
198 } else if (GuardTranslator.POLICYTYPE_MINMAX.equals(policy.getType())) {
199 validateMinMax(policy, xacmlPolicy);
200 } else if (GuardTranslator.POLICYTYPE_BLACKLIST.equals(policy.getType())) {
201 validateBlacklist(policy, xacmlPolicy);
202 } else if (GuardTranslator.POLICYTYPE_FILTER.equals(policy.getType())) {
203 validateFilter(policy, xacmlPolicy);
209 private void validateCommon(ToscaPolicy policy, PolicyType xacmlPolicy) {
210 boolean foundActor = false;
211 boolean foundOperation = false;
212 boolean foundTarget = false;
213 boolean foundControlLoop = false;
214 boolean foundTimeRange = false;
216 assertThat(xacmlPolicy.getTarget()).isNotNull();
217 assertThat(xacmlPolicy.getTarget().getAnyOf()).isNotEmpty();
218 for (AnyOfType anyOf : xacmlPolicy.getTarget().getAnyOf()) {
219 assertThat(anyOf.getAllOf()).isNotEmpty();
220 for (AllOfType allOf : anyOf.getAllOf()) {
221 assertThat(allOf.getMatch()).isNotEmpty();
222 for (MatchType match : allOf.getMatch()) {
224 // These fields are required
226 if (ToscaDictionary.ID_RESOURCE_GUARD_ACTOR.toString().equals(
227 match.getAttributeDesignator().getAttributeId())) {
228 assertThat(match.getAttributeValue().getContent()).isNotNull();
230 } else if (ToscaDictionary.ID_RESOURCE_GUARD_RECIPE.toString().equals(
231 match.getAttributeDesignator().getAttributeId())) {
232 assertThat(match.getAttributeValue().getContent()).isNotNull();
233 foundOperation = true;
236 // These fields are optional
238 if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
239 match.getAttributeDesignator().getAttributeId())) {
240 assertThat(policy.getProperties()).containsKey("target");
243 if (ToscaDictionary.ID_RESOURCE_GUARD_CLNAME.toString().equals(
244 match.getAttributeDesignator().getAttributeId())) {
245 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_CONTROLLOOP);
246 foundControlLoop = true;
248 if (XACML3.ID_ENVIRONMENT_CURRENT_TIME.toString().equals(
249 match.getAttributeDesignator().getAttributeId())) {
250 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TIMERANGE);
251 foundTimeRange = true;
257 assertThat(foundActor && foundOperation).isTrue();
258 if (policy.getProperties().containsKey("target")) {
259 assertThat(foundTarget).isTrue();
261 if (policy.getProperties().containsKey(GuardTranslator.FIELD_CONTROLLOOP)) {
262 assertThat(foundControlLoop).isTrue();
264 if (policy.getProperties().containsKey(GuardTranslator.FIELD_TIMERANGE)) {
265 assertThat(foundTimeRange).isTrue();
269 private void validateFrequency(ToscaPolicy policy, PolicyType xacmlPolicy) {
270 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
271 if (! (rule instanceof RuleType)) {
274 assertThat(((RuleType) rule).getCondition()).isNotNull();
275 assertThat(((RuleType) rule).getCondition().getExpression()).isNotNull();
279 private void validateMinMax(ToscaPolicy policy, PolicyType xacmlPolicy) {
280 boolean foundTarget = false;
281 boolean foundMinOrMax = false;
282 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
283 if (! (rule instanceof RuleType)) {
286 for (AnyOfType anyOf : ((RuleType) rule).getTarget().getAnyOf()) {
287 assertThat(anyOf.getAllOf()).isNotEmpty();
288 for (AllOfType allOf : anyOf.getAllOf()) {
289 assertThat(allOf.getMatch()).isNotEmpty();
290 for (MatchType match : allOf.getMatch()) {
291 if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
292 match.getAttributeDesignator().getAttributeId())) {
293 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TARGET);
295 } else if (ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.toString().equals(
296 match.getAttributeDesignator().getAttributeId())) {
297 assertThat(policy.getProperties().keySet()).containsAnyOf(GuardTranslator.FIELD_MIN,
298 GuardTranslator.FIELD_MAX);
299 foundMinOrMax = true;
305 assertThat(foundTarget && foundMinOrMax).isTrue();
308 private void validateBlacklist(ToscaPolicy policy, PolicyType xacmlPolicy) {
309 boolean foundBlacklist = false;
310 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
311 if (! (rule instanceof RuleType)) {
314 assertThat(((RuleType) rule).getTarget()).isNotNull();
315 assertThat(((RuleType) rule).getTarget().getAnyOf()).hasSize(1);
316 for (AnyOfType anyOf : ((RuleType) rule).getTarget().getAnyOf()) {
317 assertThat(anyOf.getAllOf()).isNotEmpty();
318 for (AllOfType allOf : anyOf.getAllOf()) {
319 assertThat(allOf.getMatch()).isNotEmpty();
320 assertThat(allOf.getMatch()).hasSize(1);
321 for (MatchType match : allOf.getMatch()) {
322 assertThat(match.getAttributeDesignator().getAttributeId())
323 .isEqualTo(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString());
324 assertThat(match.getAttributeValue().getContent()).containsAnyOf("vnf1", "vnf2");
326 // This just checks that policy did have a blacklist in it.
328 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_BLACKLIST);
329 foundBlacklist = true;
334 assertThat(foundBlacklist).isTrue();
337 private void validateFilter(ToscaPolicy policy, PolicyType xacmlPolicy) {
338 assertThat(xacmlPolicy.getRuleCombiningAlgId()).endsWith("-overrides");
339 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
340 if (! (rule instanceof RuleType)) {
343 assertThat(((RuleType) rule).getTarget()).isNotNull();
344 assertThat(((RuleType) rule).getTarget().getAnyOf()).hasSize(1);
345 for (AnyOfType anyOf : ((RuleType) rule).getTarget().getAnyOf()) {
346 assertThat(anyOf.getAllOf()).isNotEmpty();
347 for (AllOfType allOf : anyOf.getAllOf()) {
348 assertThat(allOf.getMatch()).isNotEmpty();
349 assertThat(allOf.getMatch()).hasSize(1);
350 for (MatchType match : allOf.getMatch()) {
351 assertThat(match.getAttributeDesignator().getAttributeId())
352 .startsWith(GuardPolicyRequest.PREFIX_RESOURCE_ATTRIBUTE_ID);