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();