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;
38 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
43 import org.junit.Test;
44 import org.onap.policy.common.utils.coder.StandardCoder;
45 import org.onap.policy.common.utils.coder.StandardYamlCoder;
46 import org.onap.policy.common.utils.resources.ResourceUtils;
47 import org.onap.policy.common.utils.resources.TextFileUtils;
48 import org.onap.policy.models.decisions.concepts.DecisionRequest;
49 import org.onap.policy.models.decisions.concepts.DecisionResponse;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
52 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
53 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
54 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
58 public class GuardTranslatorTest {
59 private static final Logger LOGGER = LoggerFactory.getLogger(GuardTranslatorTest.class);
60 private static final StandardYamlCoder yamlCoder = new StandardYamlCoder();
61 private static StandardCoder gson = new StandardCoder();
63 private GuardTranslator translator = new GuardTranslator();
66 public void testRequest() throws Exception {
67 DecisionRequest decisionRequest = gson.decode(
68 TextFileUtils.getTextFileAsString(
69 "src/test/resources/requests/guard.vfCount.json"),
70 DecisionRequest.class);
71 Request xacmlRequest = translator.convertRequest(decisionRequest);
73 assertThat(xacmlRequest).isNotNull();
77 public void testResponse() {
78 StdStatus status = new StdStatus(StdStatusCode.STATUS_CODE_OK);
79 StdMutableResult result = new StdMutableResult(Decision.PERMIT, status);
80 StdMutableResponse response = new StdMutableResponse(result);
82 DecisionResponse decisionResponse = translator.convertResponse(response);
83 assertThat(decisionResponse).isNotNull();
84 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
86 result = new StdMutableResult(Decision.DENY, status);
87 response = new StdMutableResponse(result);
88 decisionResponse = translator.convertResponse(response);
89 assertThat(decisionResponse).isNotNull();
90 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.DENY.toString());
92 result = new StdMutableResult(Decision.INDETERMINATE, status);
93 response = new StdMutableResponse(result);
94 decisionResponse = translator.convertResponse(response);
95 assertThat(decisionResponse).isNotNull();
96 assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
101 public void testBadPolicies() throws Exception {
102 String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-bad-policies.yaml");
104 // Serialize it into a class
106 ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
108 // Make sure all the fields are setup properly
110 JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
111 jtst.fromAuthorative(serviceTemplate);
112 ToscaServiceTemplate completedJtst = jtst.toAuthorative();
116 for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
117 for (ToscaPolicy policy : policies.values()) {
118 if ("frequency-missing-properties".equals(policy.getName())) {
119 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
120 translator.convertPolicy(policy)
121 ).withMessageContaining("Missing property limit");
122 } else if ("frequency-timewindow".equals(policy.getName())) {
123 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
124 translator.convertPolicy(policy)
125 ).withMessageContaining("timeWindow is not an integer");
126 } else if ("minmax-notarget".equals(policy.getName())) {
127 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
128 translator.convertPolicy(policy)
129 ).withMessageContaining("Missing target field in minmax policy");
130 } else if ("minmax-nominmax".equals(policy.getName())) {
131 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
132 translator.convertPolicy(policy)
133 ).withMessageContaining("Missing min or max field in minmax policy");
134 } else if ("blacklist-noblacklist".equals(policy.getName())) {
135 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
136 translator.convertPolicy(policy)
137 ).withMessageContaining("Missing blacklist");
144 public void testPolicyConversion() throws Exception {
145 String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-policies.yaml");
147 // Serialize it into a class
149 ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
151 // Make sure all the fields are setup properly
153 JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
154 jtst.fromAuthorative(serviceTemplate);
155 ToscaServiceTemplate completedJtst = jtst.toAuthorative();
159 for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
160 for (ToscaPolicy policy : policies.values()) {
162 // Convert the policy
164 if ("onap.policies.controlloop.guard.common.Unknown".equals(policy.getType())) {
165 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
166 translator.convertPolicy(policy));
169 PolicyType xacmlPolicy = (PolicyType) translator.convertPolicy(policy);
170 assertThat(xacmlPolicy).isNotNull();
174 ByteArrayOutputStream os = new ByteArrayOutputStream();
175 XACMLPolicyWriter.writePolicyFile(os, xacmlPolicy);
176 LOGGER.info(os.toString());
178 // Validate the policy
180 assertThat(xacmlPolicy.getPolicyId()).isEqualTo(policy.getName());
181 assertThat(xacmlPolicy.getVersion()).isEqualTo(policy.getVersion());
182 assertThat(xacmlPolicy.getRuleCombiningAlgId()).isNotNull();
183 validateCommon(policy, xacmlPolicy);
185 // Validate each policy type
187 if (GuardTranslator.POLICYTYPE_FREQUENCY.equals(policy.getType())) {
188 validateFrequency(policy, xacmlPolicy);
189 } else if (GuardTranslator.POLICYTYPE_MINMAX.equals(policy.getType())) {
190 validateMinMax(policy, xacmlPolicy);
191 } else if (GuardTranslator.POLICYTYPE_BLACKLIST.equals(policy.getType())) {
192 validateBlacklist(policy, xacmlPolicy);
198 private void validateCommon(ToscaPolicy policy, PolicyType xacmlPolicy) {
199 boolean foundActor = false;
200 boolean foundOperation = false;
201 boolean foundTarget = false;
202 boolean foundControlLoop = false;
203 boolean foundTimeRange = false;
205 assertThat(xacmlPolicy.getTarget()).isNotNull();
206 assertThat(xacmlPolicy.getTarget().getAnyOf()).isNotEmpty();
207 for (AnyOfType anyOf : xacmlPolicy.getTarget().getAnyOf()) {
208 assertThat(anyOf.getAllOf()).isNotEmpty();
209 for (AllOfType allOf : anyOf.getAllOf()) {
210 assertThat(allOf.getMatch()).isNotEmpty();
211 for (MatchType match : allOf.getMatch()) {
213 // These fields are required
215 if (ToscaDictionary.ID_RESOURCE_GUARD_ACTOR.toString().equals(
216 match.getAttributeDesignator().getAttributeId())) {
217 assertThat(match.getAttributeValue().getContent()).isNotNull();
219 } else if (ToscaDictionary.ID_RESOURCE_GUARD_RECIPE.toString().equals(
220 match.getAttributeDesignator().getAttributeId())) {
221 assertThat(match.getAttributeValue().getContent()).isNotNull();
222 foundOperation = true;
225 // These fields are optional
227 if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
228 match.getAttributeDesignator().getAttributeId())) {
229 assertThat(policy.getProperties()).containsKey("target");
232 if (ToscaDictionary.ID_RESOURCE_GUARD_CLNAME.toString().equals(
233 match.getAttributeDesignator().getAttributeId())) {
234 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_CONTROLLOOP);
235 foundControlLoop = true;
237 if (XACML3.ID_ENVIRONMENT_CURRENT_TIME.toString().equals(
238 match.getAttributeDesignator().getAttributeId())) {
239 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TIMERANGE);
240 foundTimeRange = true;
246 assertThat(foundActor && foundOperation).isTrue();
247 if (policy.getProperties().containsKey("target")) {
248 assertThat(foundTarget).isTrue();
250 if (policy.getProperties().containsKey(GuardTranslator.FIELD_CONTROLLOOP)) {
251 assertThat(foundControlLoop).isTrue();
253 if (policy.getProperties().containsKey(GuardTranslator.FIELD_TIMERANGE)) {
254 assertThat(foundTimeRange).isTrue();
258 private void validateFrequency(ToscaPolicy policy, PolicyType xacmlPolicy) {
259 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
260 if (! (rule instanceof RuleType)) {
263 assertThat(((RuleType) rule).getCondition()).isNotNull();
264 assertThat(((RuleType) rule).getCondition().getExpression()).isNotNull();
268 private void validateMinMax(ToscaPolicy policy, PolicyType xacmlPolicy) {
269 boolean foundTarget = false;
270 boolean foundMinOrMax = false;
271 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
272 if (! (rule instanceof RuleType)) {
275 for (AnyOfType anyOf : ((RuleType) rule).getTarget().getAnyOf()) {
276 assertThat(anyOf.getAllOf()).isNotEmpty();
277 for (AllOfType allOf : anyOf.getAllOf()) {
278 assertThat(allOf.getMatch()).isNotEmpty();
279 for (MatchType match : allOf.getMatch()) {
280 if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
281 match.getAttributeDesignator().getAttributeId())) {
282 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TARGET);
284 } else if (ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.toString().equals(
285 match.getAttributeDesignator().getAttributeId())) {
286 assertThat(policy.getProperties().keySet()).containsAnyOf(GuardTranslator.FIELD_MIN,
287 GuardTranslator.FIELD_MAX);
288 foundMinOrMax = true;
294 assertThat(foundTarget && foundMinOrMax).isTrue();
297 private void validateBlacklist(ToscaPolicy policy, PolicyType xacmlPolicy) {
298 boolean foundBlacklist = false;
299 for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
300 if (! (rule instanceof RuleType)) {
303 assertThat(((RuleType) rule).getTarget()).isNotNull();
304 assertThat(((RuleType) rule).getTarget().getAnyOf()).hasSize(1);
305 for (AnyOfType anyOf : ((RuleType) rule).getTarget().getAnyOf()) {
306 assertThat(anyOf.getAllOf()).isNotEmpty();
307 for (AllOfType allOf : anyOf.getAllOf()) {
308 assertThat(allOf.getMatch()).isNotEmpty();
309 assertThat(allOf.getMatch()).hasSize(1);
310 for (MatchType match : allOf.getMatch()) {
311 assertThat(match.getAttributeDesignator().getAttributeId())
312 .isEqualTo(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString());
313 assertThat(match.getAttributeValue().getContent()).containsAnyOf("vnf1", "vnf2");
315 // This just checks that policy did have a blacklist in it.
317 assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_BLACKLIST);
318 foundBlacklist = true;
323 assertThat(foundBlacklist).isTrue();