diff options
author | ajinkya-patil <ajinkya-patil@t-systems.com> | 2024-09-24 12:24:42 +0530 |
---|---|---|
committer | Ajinkya Patil <ajinkya-patil@t-systems.com> | 2024-10-17 09:48:50 +0000 |
commit | a7577cb59e90ef1c6ba5031b138fb1b45b828f95 (patch) | |
tree | 16156234d9ee9a427424dc0bf515cf17e3a80d24 | |
parent | d1c420217e67337bec7cee3071db995d97a4a87c (diff) |
Added tosca xacml policy type in Native Application
Added new onap.policies.native.ToscaXacml policy type in native application.
Issue-ID: POLICY-5128
Change-Id: I2b5b606f93be82b78f69c2a4d7d8f021f3db328b
Signed-off-by: ajinkya-patil <ajinkya-patil@t-systems.com>
7 files changed, 2327 insertions, 31 deletions
diff --git a/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplication.java b/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplication.java index cfe1a710..b6eeb52c 100644 --- a/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplication.java +++ b/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplication.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2024 Deutsche Telekom AG. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +41,8 @@ public class NativePdpApplication extends StdXacmlApplicationServiceProvider { private static final ToscaConceptIdentifier nativePolicyType = new ToscaConceptIdentifier( "onap.policies.native.Xacml", "1.0.0"); + private static final ToscaConceptIdentifier nativeToscaXacmlPolicyType = new ToscaConceptIdentifier( + "onap.policies.native.ToscaXacml", "1.0.0"); private NativePdpApplicationTranslator translator = new NativePdpApplicationTranslator(); /** @@ -51,11 +54,12 @@ public class NativePdpApplication extends StdXacmlApplicationServiceProvider { applicationName = "native"; actions = Arrays.asList("native"); supportedPolicyTypes.add(nativePolicyType); + supportedPolicyTypes.add(nativeToscaXacmlPolicyType); } @Override public boolean canSupportPolicyType(ToscaConceptIdentifier policyTypeId) { - return nativePolicyType.equals(policyTypeId); + return (nativePolicyType.equals(policyTypeId) || nativeToscaXacmlPolicyType.equals(policyTypeId)); } @Override diff --git a/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTranslator.java b/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTranslator.java index 3caf28f2..5e87f226 100644 --- a/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTranslator.java +++ b/applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTranslator.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2020 Nordix Foundation. + * Modifications Copyright (C) 2024 Deutsche Telekom AG. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,15 +24,40 @@ package org.onap.policy.xacml.pdp.application.nativ; +import com.att.research.xacml.api.Identifier; import com.att.research.xacml.api.Request; import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.XACML3; import com.att.research.xacml.util.XACMLPolicyScanner; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; import lombok.Getter; import lombok.NoArgsConstructor; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.DefaultsType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.FunctionType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType; import org.onap.policy.common.parameters.annotations.NotBlank; import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.models.decisions.concepts.DecisionRequest; @@ -54,40 +80,61 @@ public class NativePdpApplicationTranslator implements ToscaPolicyTranslator { private static final Logger LOGGER = LoggerFactory.getLogger(NativePdpApplicationTranslator.class); + private static final String TOSCA_XACML_POLICY_TYPE = "onap.policies.native.ToscaXacml"; + + private static final String DESCRIPTION = "description"; + + private static final String TARGET = "target"; + + private static final String VALUE = "value"; + + private static final String APPLY = "apply"; + + private static final String ONE_AND_ONLY = "-one-and-only"; + + private static final String DOUBLE = "double"; + + private Map<String, Identifier> identifierMap; + @Override public Object convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { - // - // Extract the Base64 encoded policy xml string and decode it - // - String encodedXacmlPolicy = getNativeXacmlPolicy(toscaPolicy); - String decodedXacmlPolicy; - try { - decodedXacmlPolicy = new String(Base64.getDecoder().decode(encodedXacmlPolicy), StandardCharsets.UTF_8); - } catch (IllegalArgumentException exc) { - throw new ToscaPolicyConversionException("error on Base64 decoding the native policy", exc); - } - LOGGER.debug("Decoded xacml policy {}", decodedXacmlPolicy); - // - // Scan the string and convert to xacml PolicyType - // - try (var is = new ByteArrayInputStream(decodedXacmlPolicy.getBytes(StandardCharsets.UTF_8))) { + if (TOSCA_XACML_POLICY_TYPE.equals(toscaPolicy.getType())) { + setIdentifierMap(); + return setPolicySetType(toscaPolicy); + } else { // - // Read the Policy In + // Extract the Base64 encoded policy xml string and decode it // - Object policy = XACMLPolicyScanner.readPolicy(is); - if (policy == null) { - throw new ToscaPolicyConversionException("Invalid XACML Policy"); + String encodedXacmlPolicy = getNativeXacmlPolicy(toscaPolicy); + String decodedXacmlPolicy; + try { + decodedXacmlPolicy = new String(Base64.getDecoder().decode(encodedXacmlPolicy), StandardCharsets.UTF_8); + } catch (IllegalArgumentException exc) { + throw new ToscaPolicyConversionException("error on Base64 decoding the native policy", exc); + } + LOGGER.debug("Decoded xacml policy {}", decodedXacmlPolicy); + // + // Scan the string and convert to xacml PolicyType + // + try (var is = new ByteArrayInputStream(decodedXacmlPolicy.getBytes(StandardCharsets.UTF_8))) { + // + // Read the Policy In + // + Object policy = XACMLPolicyScanner.readPolicy(is); + if (policy == null) { + throw new ToscaPolicyConversionException("Invalid XACML Policy"); + } + return policy; + } catch (IOException exc) { + throw new ToscaPolicyConversionException("Failed to read policy", exc); } - return policy; - } catch (IOException exc) { - throw new ToscaPolicyConversionException("Failed to read policy", exc); } } protected String getNativeXacmlPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { var nativeDefinition = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(), - NativeDefinition.class); + NativeDefinition.class); LOGGER.debug("Base64 encoded native xacml policy {}", nativeDefinition.getPolicy()); return nativeDefinition.getPolicy(); @@ -112,4 +159,725 @@ public class NativePdpApplicationTranslator implements ToscaPolicyTranslator { @NotBlank private String policy; } -} + + private PolicySetType setPolicySetType(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { + PolicySetType policySetType = new PolicySetType(); + policySetType.setPolicySetId(String.valueOf(toscaPolicy.getMetadata().get("policy-id"))); + policySetType.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue()); + policySetType.setVersion(String.valueOf(toscaPolicy.getMetadata().get("policy-version"))); + policySetType.setDescription(String.valueOf(toscaPolicy.getMetadata().get(DESCRIPTION))); + policySetType.setTarget(setPolicySetTarget(toscaPolicy.getMetadata().get("action"))); + for (Map<String, Object> type: (List<Map<String, Object>>) toscaPolicy.getProperties().get("policies")) { + ToscaPolicy policy = new ToscaPolicy(); + policy.setMetadata((Map<String, Object>) type.get("metadata")); + policy.setProperties((Map<String, Object>) type.get("properties")); + ObjectFactory objectFactory = new ObjectFactory(); + policySetType.getPolicySetOrPolicyOrPolicySetIdReference() + .add(objectFactory.createPolicy(convertPolicyXacml(policy))); + } + return policySetType; + } + + /** + * Generate Xacml rule implementing specified CoordinationDirective. + * + * @param toscaPolicy Incoming Tosca Policy object + * @return the generated Xacml policy type + * @throws ToscaPolicyConversionException if check xacml identifier is not present + */ + private PolicyType convertPolicyXacml(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { + var policyType = new PolicyType(); + Map<String, Object> properties = toscaPolicy.getProperties(); + setPolicyType(toscaPolicy, policyType); + try { + List<Map<String, Object>> rules = (List<Map<String, Object>>) properties.get("rules"); + for (Map<String, Object> rule : rules) { + var ruleType = new RuleType(); + if (rule.get(DESCRIPTION) != null) { + ruleType.setDescription((String) rule.get(DESCRIPTION)); + } + ruleType.setRuleId(UUID.randomUUID().toString()); + if (rule.get(TARGET) != null) { + ruleType.setTarget(setTargetType((Map<String, Object>) rule.get(TARGET))); + } + if (rule.get("condition") != null) { + ruleType.setCondition(setConditionType((Map<String, Object>) rule.get("condition"))); + } + if (rule.get("decision") == null) { + throw new ToscaPolicyConversionException("decision is mandatory in a rule"); + } + setAdviceExpression(ruleType, rule); + policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(ruleType); + } + } catch (ToscaPolicyConversionException ex) { + throw new ToscaPolicyConversionException("Invalid rule format"); + } + if (properties.get("default") != null) { + setDefaultRule((String) properties.get("default"), policyType); + } + return policyType; + } + + private void setPolicyType(ToscaPolicy toscaPolicy, PolicyType policyType) throws ToscaPolicyConversionException { + policyType.setPolicyId(String.valueOf(toscaPolicy.getMetadata().get("policy-id"))); + policyType.setVersion(String.valueOf(toscaPolicy.getMetadata().get("policy-version"))); + policyType.setDescription(String.valueOf(toscaPolicy.getMetadata().get(DESCRIPTION))); + DefaultsType defaultsType = new DefaultsType(); + defaultsType.setXPathVersion("http://www.w3.org/TR/2007/REC-xpath20-20070123"); + policyType.setPolicyDefaults(defaultsType); + Map<String, Object> properties = toscaPolicy.getProperties(); + if (properties.get("combiningAlgo") != null) { + policyType.setRuleCombiningAlgId(validateFilterPropertyFunction((String) + properties.get("combiningAlgo")).stringValue()); + } else { + policyType.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue()); + } + if (properties.get(TARGET) != null) { + policyType.setTarget(setTargetType((Map<String, Object>) properties.get(TARGET))); + } else { + policyType.setTarget(new TargetType()); + } + } + + private void setAdviceExpression(RuleType ruleType, Map<String, Object> rule) + throws ToscaPolicyConversionException { + String decision = (String) rule.get("decision"); + if ("Deny".equalsIgnoreCase(decision)) { + ruleType.setEffect(EffectType.DENY); + } else { + ruleType.setEffect(EffectType.PERMIT); + } + if (rule.get("advice") != null) { + ruleType.setAdviceExpressions(setAdvice((Map<String, Object>) rule.get("advice"), decision)); + } + } + + private void setDefaultRule(String defaultDecision, PolicyType policyType) { + var defaultRule = new RuleType(); + defaultRule.setDescription("Default Rule if none of the rules evaluate to True"); + defaultRule.setRuleId(UUID.randomUUID().toString()); + if ("Deny".equalsIgnoreCase(defaultDecision)) { + defaultRule.setEffect(EffectType.DENY); + } else { + defaultRule.setEffect(EffectType.PERMIT); + } + policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(defaultRule); + } + + private TargetType setTargetType(Map<String, Object> appliesTo) throws ToscaPolicyConversionException { + List<MatchType> listMatch = new ArrayList<>(); + try { + List<Map<String, Object>> allOffList = (List<Map<String, Object>>) appliesTo.get("anyOne"); + for (Map<String, Object> allOff : allOffList) { + for (Map<String, Object> match : (List<Map<String, Object>>) allOff.get("allOf")) { + var matchType = new MatchType(); + String operator = (String) match.get("operator"); + String datatype = getDatatype(operator); + matchType.setMatchId(validateFilterPropertyFunction(operator).stringValue()); + var valueType = setAttributeValueType(match.get(VALUE), + validateFilterPropertyFunction(datatype).stringValue()); + matchType.setAttributeValue(valueType); + String attribute = ""; + String category = ""; + if (((String) match.get("key")).contains("action")) { + attribute = validateFilterPropertyFunction((String) match + .get("key")).stringValue(); + category = XACML3.ID_ATTRIBUTE_CATEGORY_ACTION.stringValue(); + } else { + attribute = (String) match.get("key"); + category = XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(); + } + var designator = setAttributeDesignatorType(attribute, category, + validateFilterPropertyFunction(datatype).stringValue(), false); + matchType.setAttributeDesignator(designator); + listMatch.add(matchType); + } + } + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid target format"); + } + var anyOfType = new AnyOfType(); + MatchType[] matchTypes = new MatchType[listMatch.size()]; + anyOfType.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(listMatch.toArray(matchTypes))); + var target = new TargetType(); + target.getAnyOf().add(anyOfType); + return target; + } + + private TargetType setPolicySetTarget(Object value) { + var matchType = new MatchType(); + matchType.setMatchId(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue()); + var valueType = setAttributeValueType(value, XACML3.ID_DATATYPE_STRING.stringValue()); + matchType.setAttributeValue(valueType); + var designator = setAttributeDesignatorType(XACML3.ID_ACTION_ACTION_ID.stringValue(), + XACML3.ID_ATTRIBUTE_CATEGORY_ACTION.stringValue(), + XACML3.ID_DATATYPE_STRING.stringValue(), false); + matchType.setAttributeDesignator(designator); + var anyOfType = new AnyOfType(); + anyOfType.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchType)); + var target = new TargetType(); + target.getAnyOf().add(anyOfType); + return target; + } + + private ConditionType setConditionType(Map<String, Object> conditionMap) throws ToscaPolicyConversionException { + var condition = new ConditionType(); + try { + Map<String, Object> applyMap = (Map<String, Object>) conditionMap.get(APPLY); + ApplyType parentApply = setApply(applyMap); + condition.setExpression(new ObjectFactory().createApply(parentApply)); + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid condition format"); + } + return condition; + } + + private ApplyType setApply(Map<String, Object> applies) throws ToscaPolicyConversionException { + var apply = new ApplyType(); + try { + List<Object> keys = (List<Object>) applies.get("keys"); + String operator = (String) applies.get("operator"); + String datatype = getDatatype(operator); + apply.setFunctionId(validateFilterPropertyFunction(operator).stringValue()); + var factory = new ObjectFactory(); + List<Object> keyList = new ArrayList<>(); + setApplyKeys(keyList, keys, datatype, factory, apply); + setAttributeAndDesignator(keyList, apply, factory); + boolean data = switch (operator) { + case "or", "and", "n-of", "not", "all-of", "any-of", "any-of-any", "all-of-any", "all-of-all", + "any-of-all" -> false; + default -> true; + }; + if (data && applies.get("compareWith") != null) { + setCompareWith(applies, apply, factory, getDatatype(operator)); + } + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid apply format"); + } + return apply; + } + + private void setApplyKeys(List<Object> keyList, List<Object> keys, String datatype, + ObjectFactory factory, ApplyType apply) throws ToscaPolicyConversionException { + for (Object keyObject : keys) { + if (keyObject instanceof Map<?, ?>) { + if (((Map<?, ?>) keyObject).get("list") != null) { + setBagApply(apply, (List<Object>) ((Map<?, ?>) keyObject).get("list"), datatype, factory); + } else if (((Map<?, ?>) keyObject).get("function") != null) { + setFunctionType(apply, ((Map<String, String>) keyObject).get("function"), factory); + } else if (((Map<?, ?>) keyObject).get(APPLY) != null) { + keyList.add(setApply((Map<String, Object>) ((Map<?, ?>) keyObject).get(APPLY))); + } else { + throw new ToscaPolicyConversionException( + "Invalid key entry, object does not contain list, function or apply"); + } + } else { + setAttributes(keyObject, keyList, datatype, factory); + } + } + } + + private void setAttributeAndDesignator(List<Object> keyList, ApplyType apply, ObjectFactory factory) { + keyList.stream() + .sorted((firstKey, secondKey) -> { + if (firstKey instanceof AttributeValueType) { + return -1; + } else if (firstKey instanceof ApplyType) { + return 1; + } + return 0; + }) + .forEach(key -> { + if (key instanceof AttributeValueType) { + apply.getExpression().add(factory.createAttributeValue((AttributeValueType) key)); + } + if (key instanceof ApplyType) { + apply.getExpression().add(factory.createApply((ApplyType) key)); + } + }); + } + + private void setAttributes(Object key, List<Object> keyList, String datatype, ObjectFactory factory) + throws ToscaPolicyConversionException { + try { + if (key instanceof String) { + String value = (String) key; + if (value.startsWith("'") && value.endsWith("'")) { + AttributeValueType attributeValue = setAttributeValueType(value.substring(1, value.length() - 1), + validateFilterPropertyFunction(datatype).stringValue()); + keyList.add(attributeValue); + } else { + var keyDesignator = setAttributeDesignatorType(value, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(), + validateFilterPropertyFunction(datatype).stringValue(), false); + ApplyType keyApply = new ApplyType(); + keyApply.setFunctionId(validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue()); + keyApply.getExpression().add(factory.createAttributeDesignator(keyDesignator)); + keyList.add(keyApply); + } + } else { + AttributeValueType attributeValue = setAttributeValueType(key, + validateFilterPropertyFunction(datatype).stringValue()); + keyList.add(attributeValue); + } + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid string value format in keys"); + } + } + + private void setBagApply(ApplyType apply, List<Object> list, String datatype, ObjectFactory factory) + throws ToscaPolicyConversionException { + try { + var bagApply = new ApplyType(); + bagApply.setFunctionId(validateFilterPropertyFunction(datatype + "-bag").stringValue()); + for (Object attribute : list) { + if (attribute instanceof String && !(((String) attribute).startsWith("'") + && ((String) attribute).endsWith("'"))) { + var applyDesignator = new ApplyType(); + applyDesignator.setFunctionId( + validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue()); + var designator = setAttributeDesignatorType((String) attribute, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(), + validateFilterPropertyFunction(datatype).stringValue(), false); + applyDesignator.getExpression().add(factory.createAttributeDesignator(designator)); + bagApply.getExpression().add(factory.createApply(applyDesignator)); + } + } + for (Object attribute : list) { + if (attribute instanceof String) { + String value = (String) attribute; + if (value.startsWith("'") && value.endsWith("'")) { + var attributeValue = setAttributeValueType(value.substring(1, value.length() - 1), + validateFilterPropertyFunction(datatype).stringValue()); + bagApply.getExpression().add(factory.createAttributeValue(attributeValue)); + } + } else { + var attributeValue = setAttributeValueType(attribute, + validateFilterPropertyFunction(datatype).stringValue()); + bagApply.getExpression().add(factory.createAttributeValue(attributeValue)); + } + } + apply.getExpression().add(factory.createApply(bagApply)); + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid list format in keys"); + } + } + + private void setFunctionType(ApplyType apply, String function, ObjectFactory factory) + throws ToscaPolicyConversionException { + try { + var functionType = new FunctionType(); + functionType.setFunctionId(validateFilterPropertyFunction(function).stringValue()); + apply.getExpression().add(factory.createFunction(functionType)); + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid function format in keys"); + } + } + + private void setCompareWith(Map<String, Object> compareWithMap, ApplyType apply, ObjectFactory factory, + String datatype) throws ToscaPolicyConversionException { + try { + Map<String, Object> compareWith = (Map<String, Object>) compareWithMap.get("compareWith"); + if (compareWith.get(APPLY) != null) { + ApplyType compareApply = setApply((Map<String, Object>) compareWith.get(APPLY)); + apply.getExpression().add(factory.createApply(compareApply)); + } else if (compareWith.get(VALUE) != null) { + var attributeValue = setAttributeValueType(compareWith.get(VALUE), + validateFilterPropertyFunction(datatype).stringValue()); + apply.getExpression().add(factory.createAttributeValue(attributeValue)); + } else if (compareWith.get("key") != null) { + var keyDesignator = setAttributeDesignatorType((String) compareWith.get("key"), + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(), + validateFilterPropertyFunction(datatype).stringValue(), false); + var keyApply = new ApplyType(); + keyApply.setFunctionId(validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue()); + keyApply.getExpression().add(factory.createAttributeDesignator(keyDesignator)); + apply.getExpression().add(factory.createApply(keyApply)); + } else { + throw new ToscaPolicyConversionException("compareWith does not contain apply, value or key"); + } + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid compareWith format"); + } + } + + private AdviceExpressionsType setAdvice(Map<String, Object> advice, String decision) + throws ToscaPolicyConversionException { + var adviceExpressions = new AdviceExpressionsType(); + try { + var adviceExpression = new AdviceExpressionType(); + adviceExpression.setAdviceId(UUID.randomUUID().toString()); + var value = setAttributeValueType(advice.get(VALUE), XACML3.ID_DATATYPE_STRING.stringValue()); + var assignment = new AttributeAssignmentExpressionType(); + assignment.setAttributeId("urn:oasis:names:tc:xacml:2.0:example:attribute:text"); + assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue()); + assignment.setExpression(new ObjectFactory().createAttributeValue(value)); + adviceExpression.getAttributeAssignmentExpression().add(assignment); + if ("Deny".equalsIgnoreCase(decision)) { + adviceExpression.setAppliesTo(EffectType.DENY); + } else { + adviceExpression.setAppliesTo(EffectType.PERMIT); + } + adviceExpressions.getAdviceExpression().add(adviceExpression); + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid advice format"); + } + return adviceExpressions; + } + + private AttributeDesignatorType setAttributeDesignatorType(String attributeId, String category, + String dataType, Boolean mustBe) { + var keyDesignator = new AttributeDesignatorType(); + keyDesignator.setAttributeId(attributeId); + keyDesignator.setCategory(category); + keyDesignator.setDataType(dataType); + keyDesignator.setMustBePresent(mustBe); + return keyDesignator; + } + + private AttributeValueType setAttributeValueType(Object value, String dataType) { + var attributeValue = new AttributeValueType(); + attributeValue.setDataType(dataType); + attributeValue.getContent().add(value.toString()); + return attributeValue; + } + + private String getDatatype(String operator) throws ToscaPolicyConversionException { + try { + if (operator.contains("-to-")) { + return operator.split("-")[0]; + } + if (operator.contains("-from-")) { + return operator.split("-")[2]; + } + if (operator.equals("round") || operator.equals("floor")) { + return DOUBLE; + } + List<String> datatypes = Arrays.asList("string", "boolean", "integer", DOUBLE, "time", "date", "dateTime", + "dayTimeDuration", "yearMonthDuration", "anyURI", "hexBinary", "rfc822Name", "base64Binary", + "x500Name", "ipAddress", "dnsName"); + if (datatypes.stream().anyMatch(operator::contains)) { + return operator.split("-")[0]; + } + } catch (NullPointerException ex) { + throw new ToscaPolicyConversionException("Invalid operator"); + } + return operator; + } + + private void setIdentifierMap() { + identifierMap = new HashMap<>(); + identifierMap.put("string-equal", XACML3.ID_FUNCTION_STRING_EQUAL); + identifierMap.put("integer-equal", XACML3.ID_FUNCTION_INTEGER_EQUAL); + identifierMap.put("string-equal-ignore-case", XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE); + identifierMap.put("string-regexp-match", XACML3.ID_FUNCTION_STRING_REGEXP_MATCH); + identifierMap.put("string-contains", XACML3.ID_FUNCTION_STRING_CONTAINS); + identifierMap.put("string-greater-than", XACML3.ID_FUNCTION_STRING_GREATER_THAN); + identifierMap.put("string-greater-than-or-equal", XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL); + identifierMap.put("string-less-than", XACML3.ID_FUNCTION_STRING_LESS_THAN); + identifierMap.put("string-less-than-or-equal", XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL); + identifierMap.put("string-starts-with", XACML3.ID_FUNCTION_STRING_STARTS_WITH); + identifierMap.put("string-ends-with", XACML3.ID_FUNCTION_STRING_ENDS_WITH); + identifierMap.put("integer-greater-than", XACML3.ID_FUNCTION_INTEGER_GREATER_THAN); + identifierMap.put("integer-greater-than-or-equal", XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL); + identifierMap.put("integer-less-than", XACML3.ID_FUNCTION_INTEGER_LESS_THAN); + identifierMap.put("integer-less-than-or-equal", XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL); + identifierMap.put("double-greater-than", XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN); + identifierMap.put("double-greater-than-or-equal", XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL); + identifierMap.put("double-less-than", XACML3.ID_FUNCTION_DOUBLE_LESS_THAN); + identifierMap.put("double-less-than-or-equal", XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL); + identifierMap.put("datetime-add-daytimeduration", XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION); + identifierMap.put("datetime-add-yearmonthduration", XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION); + identifierMap.put("datetime-subtract-daytimeturation", XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION); + identifierMap.put("datetime-subtract-yearmonthduration", + XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION); + identifierMap.put("date-add-yearmonthduration", XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION); + identifierMap.put("date-subtract-yearmonthduration", XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION); + identifierMap.put("time-greater-than", XACML3.ID_FUNCTION_TIME_GREATER_THAN); + identifierMap.put("time-greater-than-or-equal", XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL); + identifierMap.put("time-less-than", XACML3.ID_FUNCTION_TIME_LESS_THAN); + identifierMap.put("time-less-than-or-equal", XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL); + identifierMap.put("datetime-greater-than", XACML3.ID_FUNCTION_DATETIME_GREATER_THAN); + identifierMap.put("datetime-greater-than-or-equal", XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL); + identifierMap.put("datetime-less-than", XACML3.ID_FUNCTION_DATETIME_LESS_THAN); + identifierMap.put("datetime-less-than-or-equal", XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL); + identifierMap.put("date-greater-than", XACML3.ID_FUNCTION_DATE_GREATER_THAN); + identifierMap.put("date-greater-than-or-equal", XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL); + identifierMap.put("date-less-than", XACML3.ID_FUNCTION_DATE_LESS_THAN); + identifierMap.put("date-less-than-or-equal", XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL); + identifierMap.put("boolean-one-and-only", XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY); + identifierMap.put("string-is-in", XACML3.ID_FUNCTION_STRING_IS_IN); + identifierMap.put("integer-is-in", XACML3.ID_FUNCTION_INTEGER_IS_IN); + identifierMap.put("boolean-is-in", XACML3.ID_FUNCTION_BOOLEAN_IS_IN); + identifierMap.put("double-is-in", XACML3.ID_FUNCTION_DOUBLE_IS_IN); + identifierMap.put("integer-add", XACML3.ID_FUNCTION_INTEGER_ADD); + identifierMap.put("double-add", XACML3.ID_FUNCTION_DOUBLE_ADD); + identifierMap.put("integer-subtract", XACML3.ID_FUNCTION_INTEGER_SUBTRACT); + identifierMap.put("double-subtract", XACML3.ID_FUNCTION_DOUBLE_SUBTRACT); + identifierMap.put("integer-multiply", XACML3.ID_FUNCTION_INTEGER_MULTIPLY); + identifierMap.put("double-multiply", XACML3.ID_FUNCTION_DOUBLE_MULTIPLY); + identifierMap.put("integer-divide", XACML3.ID_FUNCTION_INTEGER_DIVIDE); + identifierMap.put("double-divide", XACML3.ID_FUNCTION_DOUBLE_DIVIDE); + identifierMap.put("integer-mod", XACML3.ID_FUNCTION_INTEGER_MOD); + identifierMap.put("integer-abs", XACML3.ID_FUNCTION_INTEGER_ABS); + identifierMap.put("double-abs", XACML3.ID_FUNCTION_DOUBLE_ABS); + identifierMap.put("integer-to-double", XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE); + identifierMap.put("yearmonthduration-equal", XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL); + identifierMap.put("anyuri-equal", XACML3.ID_FUNCTION_ANYURI_EQUAL); + identifierMap.put("hexbinary-equal", XACML3.ID_FUNCTION_HEXBINARY_EQUAL); + identifierMap.put("rfc822name-equal", XACML3.ID_FUNCTION_RFC822NAME_EQUAL); + identifierMap.put("x500name-equal", XACML3.ID_FUNCTION_X500NAME_EQUAL); + identifierMap.put("string-from-ipaddress", XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS); + identifierMap.put("string-from-dnsname", XACML3.ID_FUNCTION_STRING_FROM_DNSNAME); + + identifierMap.put("boolean-equal", XACML3.ID_FUNCTION_BOOLEAN_EQUAL); + identifierMap.put("double-equal", XACML3.ID_FUNCTION_DOUBLE_EQUAL); + identifierMap.put("date-equal", XACML3.ID_FUNCTION_DATE_EQUAL); + identifierMap.put("time-equal", XACML3.ID_FUNCTION_TIME_EQUAL); + identifierMap.put("datetime-equal", XACML3.ID_FUNCTION_DATETIME_EQUAL); + identifierMap.put("daytimeduration-equal", XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL); + identifierMap.put("base64binary-equal", XACML3.ID_FUNCTION_BASE64BINARY_EQUAL); + identifierMap.put("round", XACML3.ID_FUNCTION_ROUND); + identifierMap.put("floor", XACML3.ID_FUNCTION_FLOOR); + identifierMap.put("string-normalize-space", XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE); + identifierMap.put("string-normalize-to-lower-case", XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE); + identifierMap.put("double-to-integer", XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER); + identifierMap.put("present", XACML3.ID_FUNCTION_PRESENT); + identifierMap.put("time-in-range", XACML3.ID_FUNCTION_TIME_IN_RANGE); + identifierMap.put("string-bag-size", XACML3.ID_FUNCTION_STRING_BAG_SIZE); + identifierMap.put("boolean-bag-size", XACML3.ID_FUNCTION_BOOLEAN_BAG_SIZE); + identifierMap.put("integer-bag-size", XACML3.ID_FUNCTION_INTEGER_BAG_SIZE); + identifierMap.put("double-bag-size", XACML3.ID_FUNCTION_DOUBLE_BAG_SIZE); + identifierMap.put("time-bag-size", XACML3.ID_FUNCTION_TIME_BAG_SIZE); + identifierMap.put("time-is-in", XACML3.ID_FUNCTION_TIME_IS_IN); + identifierMap.put("time-bag", XACML3.ID_FUNCTION_TIME_BAG); + identifierMap.put("date-bag-size", XACML3.ID_FUNCTION_DATE_BAG_SIZE); + identifierMap.put("date-is-in", XACML3.ID_FUNCTION_DATE_IS_IN); + identifierMap.put("date-bag", XACML3.ID_FUNCTION_DATE_BAG); + identifierMap.put("datetime-bag-size", XACML3.ID_FUNCTION_DATETIME_BAG_SIZE); + identifierMap.put("datetime-is-in", XACML3.ID_FUNCTION_DATETIME_IS_IN); + identifierMap.put("datetime-bag", XACML3.ID_FUNCTION_DATETIME_BAG); + identifierMap.put("anyuri-bag-size", XACML3.ID_FUNCTION_ANYURI_BAG_SIZE); + identifierMap.put("anyuri-is-in", XACML3.ID_FUNCTION_ANYURI_IS_IN); + identifierMap.put("anyuri-bag", XACML3.ID_FUNCTION_ANYURI_BAG); + identifierMap.put("hexbinary-bag-size", XACML3.ID_FUNCTION_HEXBINARY_BAG_SIZE); + identifierMap.put("hexbinary-is-in", XACML3.ID_FUNCTION_HEXBINARY_IS_IN); + identifierMap.put("hexbinary-bag", XACML3.ID_FUNCTION_HEXBINARY_BAG); + identifierMap.put("base64binary-bag-size", XACML3.ID_FUNCTION_BASE64BINARY_BAG_SIZE); + identifierMap.put("base64binary-is-in", XACML3.ID_FUNCTION_BASE64BINARY_IS_IN); + identifierMap.put("base64binary-bag", XACML3.ID_FUNCTION_BASE64BINARY_BAG); + identifierMap.put("daytimeduration-bag-size", XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE); + identifierMap.put("daytimeduration-is-in", XACML3.ID_FUNCTION_DAYTIMEDURATION_IS_IN); + identifierMap.put("daytimeduration-bag", XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG); + identifierMap.put("yearmonthduration-bag-size", XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE); + identifierMap.put("yearmonthduration-is-in", XACML3.ID_FUNCTION_YEARMONTHDURATION_IS_IN); + identifierMap.put("yearmonthduration-bag", XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG); + identifierMap.put("x500name-one-and-only", XACML3.ID_FUNCTION_X500NAME_ONE_AND_ONLY); + identifierMap.put("x500name-bag-size", XACML3.ID_FUNCTION_X500NAME_BAG_SIZE); + identifierMap.put("x500name-is-in", XACML3.ID_FUNCTION_X500NAME_IS_IN); + identifierMap.put("x500name-bag", XACML3.ID_FUNCTION_X500NAME_BAG); + identifierMap.put("rfc822name-one-and-only", XACML3.ID_FUNCTION_RFC822NAME_ONE_AND_ONLY); + identifierMap.put("rfc822name-bag-size", XACML3.ID_FUNCTION_RFC822NAME_BAG_SIZE); + identifierMap.put("rfc822name-is-in", XACML3.ID_FUNCTION_RFC822NAME_IS_IN); + identifierMap.put("rfc822name-bag", XACML3.ID_FUNCTION_RFC822NAME_BAG); + identifierMap.put("ipaddress-one-and-only", XACML3.ID_FUNCTION_IPADDRESS_ONE_AND_ONLY); + identifierMap.put("ipaddress-bag-size", XACML3.ID_FUNCTION_IPADDRESS_BAG_SIZE); + identifierMap.put("ipaddress-is-in", XACML3.ID_FUNCTION_IPADDRESS_IS_IN); + identifierMap.put("ipaddress-bag", XACML3.ID_FUNCTION_IPADDRESS_BAG); + identifierMap.put("dnsname-one-and-only", XACML3.ID_FUNCTION_DNSNAME_ONE_AND_ONLY); + identifierMap.put("dnsname-bag-size", XACML3.ID_FUNCTION_DNSNAME_BAG_SIZE); + identifierMap.put("dnsname-is-in", XACML3.ID_FUNCTION_DNSNAME_IS_IN); + identifierMap.put("dnsname-bag", XACML3.ID_FUNCTION_DNSNAME_BAG); + identifierMap.put("string-concatenate", XACML3.ID_FUNCTION_STRING_CONCATENATE); + identifierMap.put("boolean-from-string", XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING); + identifierMap.put("string-from-boolean", XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN); + identifierMap.put("integer-from-string", XACML3.ID_FUNCTION_INTEGER_FROM_STRING); + identifierMap.put("string-from-integer", XACML3.ID_FUNCTION_STRING_FROM_INTEGER); + identifierMap.put("double-from-string", XACML3.ID_FUNCTION_DOUBLE_FROM_STRING); + identifierMap.put("string-from-double", XACML3.ID_FUNCTION_STRING_FROM_DOUBLE); + identifierMap.put("time-from-string", XACML3.ID_FUNCTION_TIME_FROM_STRING); + identifierMap.put("string-from-time", XACML3.ID_FUNCTION_STRING_FROM_TIME); + identifierMap.put("date-from-string", XACML3.ID_FUNCTION_DATE_FROM_STRING); + identifierMap.put("string-from-date", XACML3.ID_FUNCTION_STRING_FROM_DATE); + identifierMap.put("datetime-from-string", XACML3.ID_FUNCTION_DATETIME_FROM_STRING); + identifierMap.put("string-from-datetime", XACML3.ID_FUNCTION_STRING_FROM_DATETIME); + identifierMap.put("anyuri-from-string", XACML3.ID_FUNCTION_ANYURI_FROM_STRING); + identifierMap.put("string-from-anyuri", XACML3.ID_FUNCTION_STRING_FROM_ANYURI); + identifierMap.put("daytimeduration-from-string", XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING); + identifierMap.put("string-from-daytimeturation", XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION); + identifierMap.put("yearmonthduration-from-string", XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING); + identifierMap.put("string-from-yearmonthduration", XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION); + identifierMap.put("x500name-from-string", XACML3.ID_FUNCTION_X500NAME_FROM_STRING); + identifierMap.put("string-from-x500name", XACML3.ID_FUNCTION_STRING_FROM_X500NAME); + identifierMap.put("rfc822name-from-string", XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING); + identifierMap.put("string-from-rfc822name", XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME); + identifierMap.put("ipaddress-from-string", XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING); + identifierMap.put("dnsname-from-string", XACML3.ID_FUNCTION_DNSNAME_FROM_STRING); + identifierMap.put("anyuri-starts-with", XACML3.ID_FUNCTION_ANYURI_STARTS_WITH); + identifierMap.put("anyuri-ends-with", XACML3.ID_FUNCTION_ANYURI_ENDS_WITH); + identifierMap.put("anyuri-contains", XACML3.ID_FUNCTION_ANYURI_CONTAINS); + identifierMap.put("string-substring", XACML3.ID_FUNCTION_STRING_SUBSTRING); + identifierMap.put("anyuri-substring", XACML3.ID_FUNCTION_ANYURI_SUBSTRING); + identifierMap.put("map", XACML3.ID_FUNCTION_MAP); + identifierMap.put("x500name-match", XACML3.ID_FUNCTION_X500NAME_MATCH); + identifierMap.put("rfc822name-match", XACML3.ID_FUNCTION_RFC822NAME_MATCH); + identifierMap.put("anyuri-regexp-match", XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH); + identifierMap.put("ipaddress-regexp-match", XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH); + identifierMap.put("dnsname-regexp-match", XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH); + identifierMap.put("rfc822name-regexp-match", XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH); + identifierMap.put("x500name-regexp-match", XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH); + identifierMap.put("xpath-node-count", XACML3.ID_FUNCTION_XPATH_NODE_COUNT); + identifierMap.put("xpath-node-equal", XACML3.ID_FUNCTION_XPATH_NODE_EQUAL); + identifierMap.put("xpath-node-match", XACML3.ID_FUNCTION_XPATH_NODE_MATCH); + identifierMap.put("string-intersection", XACML3.ID_FUNCTION_STRING_INTERSECTION); + identifierMap.put("string-at-least-one-member-of", XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("string-union", XACML3.ID_FUNCTION_STRING_UNION); + identifierMap.put("string-subset", XACML3.ID_FUNCTION_STRING_SUBSET); + identifierMap.put("string-set-equals", XACML3.ID_FUNCTION_STRING_SET_EQUALS); + identifierMap.put("boolean-intersection", XACML3.ID_FUNCTION_BOOLEAN_INTERSECTION); + identifierMap.put("boolean-at-least-one-member-of", XACML3.ID_FUNCTION_BOOLEAN_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("boolean-union", XACML3.ID_FUNCTION_BOOLEAN_UNION); + identifierMap.put("boolean-subset", XACML3.ID_FUNCTION_BOOLEAN_SUBSET); + identifierMap.put("boolean-set-equals", XACML3.ID_FUNCTION_BOOLEAN_SET_EQUALS); + identifierMap.put("integer-intersection", XACML3.ID_FUNCTION_INTEGER_INTERSECTION); + identifierMap.put("integer-at-least-one-member-of", XACML3.ID_FUNCTION_INTEGER_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("integer-union", XACML3.ID_FUNCTION_INTEGER_UNION); + identifierMap.put("integer-subset", XACML3.ID_FUNCTION_INTEGER_SUBSET); + identifierMap.put("integer-set-equals", XACML3.ID_FUNCTION_INTEGER_SET_EQUALS); + identifierMap.put("double-intersection", XACML3.ID_FUNCTION_DOUBLE_INTERSECTION); + identifierMap.put("double-at-least-one-member-of", XACML3.ID_FUNCTION_DOUBLE_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("double-union", XACML3.ID_FUNCTION_DOUBLE_UNION); + identifierMap.put("double-subset", XACML3.ID_FUNCTION_DOUBLE_SUBSET); + identifierMap.put("double-set-equals", XACML3.ID_FUNCTION_DOUBLE_SET_EQUALS); + identifierMap.put("time-intersection", XACML3.ID_FUNCTION_TIME_INTERSECTION); + identifierMap.put("time-at-least-one-member-of", XACML3.ID_FUNCTION_TIME_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("time-union", XACML3.ID_FUNCTION_TIME_UNION); + identifierMap.put("time-subset", XACML3.ID_FUNCTION_TIME_SUBSET); + identifierMap.put("time-set-equals", XACML3.ID_FUNCTION_TIME_SET_EQUALS); + identifierMap.put("date-intersection", XACML3.ID_FUNCTION_DATE_INTERSECTION); + identifierMap.put("date-at-least-one-member-of", XACML3.ID_FUNCTION_DATE_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("date-union", XACML3.ID_FUNCTION_DATE_UNION); + identifierMap.put("date-subset", XACML3.ID_FUNCTION_DATE_SUBSET); + identifierMap.put("date-set-equals", XACML3.ID_FUNCTION_DATE_SET_EQUALS); + identifierMap.put("datetime-intersection", XACML3.ID_FUNCTION_DATETIME_INTERSECTION); + identifierMap.put("datetime-at-least-one-member-of", XACML3.ID_FUNCTION_DATETIME_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("datetime-union", XACML3.ID_FUNCTION_DATETIME_UNION); + identifierMap.put("datetime-subset", XACML3.ID_FUNCTION_DATETIME_SUBSET); + identifierMap.put("datetime-set-equals", XACML3.ID_FUNCTION_DATETIME_SET_EQUALS); + + identifierMap.put("anyuri-intersection", XACML3.ID_FUNCTION_ANYURI_INTERSECTION); + identifierMap.put("anyuri-at-least-one-member-of", XACML3.ID_FUNCTION_ANYURI_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("anyuri-union", XACML3.ID_FUNCTION_ANYURI_UNION); + identifierMap.put("anyuri-subset", XACML3.ID_FUNCTION_ANYURI_SUBSET); + identifierMap.put("anyuri-set-equals", XACML3.ID_FUNCTION_ANYURI_SET_EQUALS); + identifierMap.put("hexbinary-intersection", XACML3.ID_FUNCTION_HEXBINARY_INTERSECTION); + identifierMap.put("hexbinary-at-least-one-member-of", XACML3.ID_FUNCTION_HEXBINARY_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("hexbinary-union", XACML3.ID_FUNCTION_HEXBINARY_UNION); + identifierMap.put("hexbinary-subset", XACML3.ID_FUNCTION_HEXBINARY_SUBSET); + identifierMap.put("hexbinary-set-equals", XACML3.ID_FUNCTION_HEXBINARY_SET_EQUALS); + identifierMap.put("base64binary-intersection", XACML3.ID_FUNCTION_BASE64BINARY_INTERSECTION); + identifierMap.put("base64binary-at-least-one-member-of", + XACML3.ID_FUNCTION_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("base64binary-union", XACML3.ID_FUNCTION_BASE64BINARY_UNION); + identifierMap.put("base64binary-subset", XACML3.ID_FUNCTION_BASE64BINARY_SUBSET); + identifierMap.put("base64binary-set-equals", XACML3.ID_FUNCTION_BASE64BINARY_SET_EQUALS); + identifierMap.put("daytimeduration-intersection", XACML3.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION); + identifierMap.put("daytimeduration-at-least-one-member-of", + XACML3.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("daytimeduration-union", XACML3.ID_FUNCTION_DAYTIMEDURATION_UNION); + identifierMap.put("daytimeduration-subset", XACML3.ID_FUNCTION_DAYTIMEDURATION_SUBSET); + identifierMap.put("daytimeduration-set-equals", XACML3.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS); + identifierMap.put("yearmonthduration-intersection", XACML3.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION); + identifierMap.put("yearmonthduration-at-least-one-member-of", + XACML3.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("yearmonthduration-union", XACML3.ID_FUNCTION_YEARMONTHDURATION_UNION); + identifierMap.put("yearmonthduration-subset", XACML3.ID_FUNCTION_YEARMONTHDURATION_SUBSET); + identifierMap.put("yearmonthduration-set-equals", XACML3.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS); + identifierMap.put("x500name-intersection", XACML3.ID_FUNCTION_X500NAME_INTERSECTION); + identifierMap.put("x500name-at-least-one-member-of", XACML3.ID_FUNCTION_X500NAME_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("x500name-union", XACML3.ID_FUNCTION_X500NAME_UNION); + identifierMap.put("x500name-subset", XACML3.ID_FUNCTION_X500NAME_SUBSET); + identifierMap.put("x500name-set-equals", XACML3.ID_FUNCTION_X500NAME_SET_EQUALS); + identifierMap.put("rfc822name-intersection", XACML3.ID_FUNCTION_RFC822NAME_INTERSECTION); + identifierMap.put("rfc822name-at-least-one-member-of", XACML3.ID_FUNCTION_RFC822NAME_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("rfc822name-union", XACML3.ID_FUNCTION_RFC822NAME_UNION); + identifierMap.put("rfc822name-subset", XACML3.ID_FUNCTION_RFC822NAME_SUBSET); + identifierMap.put("rfc822name-set-equals", XACML3.ID_FUNCTION_RFC822NAME_SET_EQUALS); + identifierMap.put("ipaddress-intersection", XACML3.ID_FUNCTION_IPADDRESS_INTERSECTION); + identifierMap.put("ipaddress-at-least-one-member-of", XACML3.ID_FUNCTION_IPADDRESS_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("ipaddress-union", XACML3.ID_FUNCTION_IPADDRESS_UNION); + identifierMap.put("ipaddress-subset", XACML3.ID_FUNCTION_IPADDRESS_SUBSET); + identifierMap.put("ipaddress-set-equals", XACML3.ID_FUNCTION_IPADDRESS_SET_EQUALS); + identifierMap.put("dnsname-intersection", XACML3.ID_FUNCTION_DNSNAME_INTERSECTION); + identifierMap.put("dnsname-at-least-one-member-of", XACML3.ID_FUNCTION_DNSNAME_AT_LEAST_ONE_MEMBER_OF); + identifierMap.put("dnsname-union", XACML3.ID_FUNCTION_DNSNAME_UNION); + identifierMap.put("dnsname-subset", XACML3.ID_FUNCTION_DNSNAME_SUBSET); + identifierMap.put("dnsname-set-equals", XACML3.ID_FUNCTION_DNSNAME_SET_EQUALS); + identifierMap.put("access-permitted", XACML3.ID_FUNCTION_ACCESS_PERMITTED); + + // function condition + identifierMap.put("or", XACML3.ID_FUNCTION_OR); + identifierMap.put("and", XACML3.ID_FUNCTION_AND); + identifierMap.put("n-of", XACML3.ID_FUNCTION_N_OF); + identifierMap.put("not", XACML3.ID_FUNCTION_NOT); + identifierMap.put("any-of", XACML3.ID_FUNCTION_ANY_OF); + identifierMap.put("all-of", XACML3.ID_FUNCTION_ALL_OF); + identifierMap.put("any-of-any", XACML3.ID_FUNCTION_ANY_OF_ANY); + identifierMap.put("all-of-any", XACML3.ID_FUNCTION_ALL_OF_ANY); + identifierMap.put("any-of-all", XACML3.ID_FUNCTION_ANY_OF_ALL); + identifierMap.put("all-of-all", XACML3.ID_FUNCTION_ALL_OF_ALL); + + // function ids + identifierMap.put("string-one-and-only", XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY); + identifierMap.put("integer-one-and-only", XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY); + identifierMap.put("double-one-and-only", XACML3.ID_FUNCTION_DOUBLE_ONE_AND_ONLY); + identifierMap.put("time-one-and-only", XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY); + identifierMap.put("date-one-and-only", XACML3.ID_FUNCTION_DATE_ONE_AND_ONLY); + identifierMap.put("datetime-one-and-only", XACML3.ID_FUNCTION_DATETIME_ONE_AND_ONLY); + identifierMap.put("anyuri-one-and-only", XACML3.ID_FUNCTION_ANYURI_ONE_AND_ONLY); + identifierMap.put("hexbinary-one-and-only", XACML3.ID_FUNCTION_HEXBINARY_ONE_AND_ONLY); + identifierMap.put("base64binary-one-and-only", XACML3.ID_FUNCTION_BASE64BINARY_ONE_AND_ONLY); + identifierMap.put("daytimeduration-one-and-only", XACML3.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY); + identifierMap.put("yearmonthduration-one-and-only", XACML3.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY); + + //attribute ids + identifierMap.put("action-id", XACML3.ID_ACTION_ACTION_ID); + + // algorithm + identifierMap.put("first-applicable", XACML3.ID_RULE_FIRST_APPLICABLE); + identifierMap.put("deny-overrides", XACML3.ID_RULE_DENY_UNLESS_PERMIT); + identifierMap.put("permit-overrides", XACML3.ID_RULE_PERMIT_UNLESS_DENY); + identifierMap.put("only-one-applicable", XACML3.ID_RULE_ONLY_ONE_APPLICABLE); + + // data types + identifierMap.put("string", XACML3.ID_DATATYPE_STRING); + identifierMap.put("boolean", XACML3.ID_DATATYPE_BOOLEAN); + identifierMap.put("integer", XACML3.ID_DATATYPE_INTEGER); + identifierMap.put(DOUBLE, XACML3.ID_DATATYPE_DOUBLE); + identifierMap.put("time", XACML3.ID_DATATYPE_TIME); + identifierMap.put("date", XACML3.ID_DATATYPE_DATE); + identifierMap.put("datetime", XACML3.ID_DATATYPE_DATETIME); + identifierMap.put("daytimeduration", XACML3.ID_DATATYPE_DAYTIMEDURATION); + identifierMap.put("yearmonthduration", XACML3.ID_DATATYPE_YEARMONTHDURATION); + identifierMap.put("anyuri", XACML3.ID_DATATYPE_ANYURI); + identifierMap.put("hexbinary", XACML3.ID_DATATYPE_HEXBINARY); + identifierMap.put("base64binary", XACML3.ID_DATATYPE_BASE64BINARY); + identifierMap.put("rfc822name", XACML3.ID_DATATYPE_RFC822NAME); + identifierMap.put("x500name", XACML3.ID_DATATYPE_X500NAME); + identifierMap.put("ipaddress", XACML3.ID_DATATYPE_IPADDRESS); + identifierMap.put("dnsname", XACML3.ID_DATATYPE_DNSNAME); + + identifierMap.put("string-bag", XACML3.ID_FUNCTION_STRING_BAG); + identifierMap.put("boolean-bag", XACML3.ID_FUNCTION_BOOLEAN_BAG); + identifierMap.put("integer-bag", XACML3.ID_FUNCTION_INTEGER_BAG); + identifierMap.put("double-bag", XACML3.ID_FUNCTION_DOUBLE_BAG); + } + + private Identifier validateFilterPropertyFunction(String operator) throws ToscaPolicyConversionException { + if (identifierMap.containsKey(operator.toLowerCase())) { + return identifierMap.get(operator.toLowerCase()); + } else { + throw new ToscaPolicyConversionException("Unexpected value " + operator); + } + } +}
\ No newline at end of file diff --git a/applications/native/src/test/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTest.java b/applications/native/src/test/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTest.java index 47e92c09..04fe1fe8 100644 --- a/applications/native/src/test/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTest.java +++ b/applications/native/src/test/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTest.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2021, 2024 Nordix Foundation. + * Modifications Copyright (C) 2024 Deutsche Telekom AG. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +37,11 @@ import java.nio.file.Path; import java.util.Map; import java.util.Properties; import java.util.ServiceLoader; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardYamlCoder; import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.common.utils.resources.TextFileUtils; @@ -47,6 +50,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils; import org.onap.policy.pdp.xacml.xacmltest.TestUtils; @@ -79,12 +83,12 @@ class NativePdpApplicationTest { // XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.resolve(filename).toFile(); propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties", - properties, myCreator); + properties, myCreator); // // Load service // ServiceLoader<XacmlApplicationServiceProvider> applicationLoader = - ServiceLoader.load(XacmlApplicationServiceProvider.class); + ServiceLoader.load(XacmlApplicationServiceProvider.class); // // Find the native application and save for use in all the tests // @@ -130,9 +134,11 @@ class NativePdpApplicationTest { NativePdpApplication application = new NativePdpApplication(); assertThat(application.canSupportPolicyType(new ToscaConceptIdentifier( - "onap.policies.native.Xacml", "1.0.0"))).isTrue(); + "onap.policies.native.Xacml", "1.0.0"))).isTrue(); assertThat(application.canSupportPolicyType(new ToscaConceptIdentifier( - "onap.policies.native.SomethingElse", "1.0.0"))).isFalse(); + "onap.policies.native.ToscaXacml", "1.0.0"))).isTrue(); + assertThat(application.canSupportPolicyType(new ToscaConceptIdentifier( + "onap.policies.native.SomethingElse", "1.0.0"))).isFalse(); assertThat(application.actionDecisionsSupported()).contains("native"); } @@ -187,6 +193,63 @@ class NativePdpApplicationTest { requestAndCheckDecision(request); } + @Test + void testNativeToscaXacmlPolicy() throws Exception { + String policySetTypeYaml = ResourceUtils + .getResourceAsString("src/test/resources/policies/native.toscapolicy.yaml"); + checkPolicySetType(policySetTypeYaml); + } + + @Test + void testBadToscaXacmlPolicyRule() throws Exception { + NativePdpApplicationTranslator translator = new NativePdpApplicationTranslator(); + String policyYaml = ResourceUtils + .getResourceAsString("src/test/resources/policies/bad.native.toscapolicy.yaml"); + + ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class); + JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate(); + jtst.fromAuthorative(serviceTemplate); + ToscaServiceTemplate completedJtst = jtst.toAuthorative(); + + for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) { + for (ToscaPolicy policy : policies.values()) { + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> + translator.convertPolicy(policy) + ).as((String) policy.getMetadata().get("policy-id")) + .withMessageContaining("Invalid rule format"); + } + } + } + + @Test + void testBadToscaXacmlPolicyTarget() throws Exception { + NativePdpApplicationTranslator translator = new NativePdpApplicationTranslator(); + String policyYaml = ResourceUtils + .getResourceAsString("src/test/resources/policies/bad.native.tosca.policy.target.yaml"); + + ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class); + JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate(); + jtst.fromAuthorative(serviceTemplate); + ToscaServiceTemplate completedJtst = jtst.toAuthorative(); + + for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) { + for (ToscaPolicy policy : policies.values()) { + if ("bad.tosca.policy.test".equals(policy.getName())) { + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> + translator.convertPolicy(policy) + ).as((String) policy.getMetadata().get("policy-id")) + .withMessageContaining("Invalid operator"); + } + if ("bad.tosca.policy.target.test".equals(policy.getName())) { + assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> + translator.convertPolicy(policy) + ).as((String) policy.getMetadata().get("policy-id")) + .withMessageContaining("Invalid target format"); + } + } + } + } + /** * Request a decision and check that it matches expectation. * @@ -218,4 +281,26 @@ class NativePdpApplicationTest { assertThat(decision).hasToString(NativePdpApplicationTest.PERMIT); LOGGER.info("Xacml response we received {}", DOMResponse.toString(response)); } + + private void checkPolicySetType(String policySetTypeYaml) throws ToscaPolicyConversionException, CoderException { + NativePdpApplicationTranslator translator = new NativePdpApplicationTranslator(); + ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policySetTypeYaml, ToscaServiceTemplate.class); + JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate(); + jtst.fromAuthorative(serviceTemplate); + ToscaServiceTemplate completedJtst = jtst.toAuthorative(); + for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) { + for (ToscaPolicy policy : policies.values()) { + try { + service.loadPolicy(policy); + } catch (XacmlApplicationException e) { + LOGGER.error("Application failed to load policy", e); + } + PolicySetType policySetType = (PolicySetType) translator.convertPolicy(policy); + assertThat(policySetType).isNotNull(); + assertThat(policySetType.getPolicySetId()).isEqualTo("tosca.policy.test"); + assertThat(policySetType.getPolicyCombiningAlgId()) + .isEqualTo("urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"); + } + } + } } diff --git a/applications/native/src/test/resources/policies/bad.native.tosca.policy.target.yaml b/applications/native/src/test/resources/policies/bad.native.tosca.policy.target.yaml new file mode 100644 index 00000000..2d2d966e --- /dev/null +++ b/applications/native/src/test/resources/policies/bad.native.tosca.policy.target.yaml @@ -0,0 +1,78 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + inputs: {} + policies: + - bad.tosca.policy.test: + type: onap.policies.native.ToscaXacml + type_version: 1.0.0 + properties: + policies: + - properties: + description: Policy that allows minimum number of available cells for + a slice to be feasible, prio=1 + target: + anyOne: + - allOf: + - key: action-id + operator: + value: "1" + rules: + - condition: + apply: + keys: + - feasibleCellsForSlice + operator: integer-equal + compareWith: + value: 2 + decision: Permit + advice: + value: Slice is feasible since minumum number of cells are available + metadata: + policy-id: bad.tosca.policy.test.1 + policy-version: 1.0.0 + name: bad.tosca.policy.test + version: 3.0.0 + metadata: + action: sfc-policy + description: This policy set specifies the conditions for slice feasibility + based on availability of cells + policy-id: bad.tosca.policy.test + policy-version: 3.0.0 + - bad.tosca.policy.target.test: + type: onap.policies.native.ToscaXacml + type_version: 1.0.0 + properties: + policies: + - properties: + description: Policy that allows minimum number of available cells for + a slice to be feasible, prio=1 + target: + anyOne: + - allOf: + - key: action-id + operator: integer-equal + value: + rules: + - condition: + apply: + keys: + - feasibleCellsForSlice + operator: integer-equal + compareWith: + value: 2 + decision: Permit + advice: + value: Slice is feasible since minumum number of cells are available + metadata: + policy-id: bad.tosca.policy.test.1 + policy-version: 1.0.0 + name: bad.tosca.policy.target.test + version: 3.0.0 + metadata: + action: sfc-policy + description: This policy set specifies the conditions for slice feasibility + based on availability of cells + policy-id: bad.tosca.policy.target.test + policy-version: 3.0.0 +name: ToscaServiceTemplateSimple +version: 1.0.0 diff --git a/applications/native/src/test/resources/policies/bad.native.toscapolicy.yaml b/applications/native/src/test/resources/policies/bad.native.toscapolicy.yaml new file mode 100644 index 00000000..d19f0854 --- /dev/null +++ b/applications/native/src/test/resources/policies/bad.native.toscapolicy.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + inputs: {} + policies: + - bad.tosca.policy.test: + type: onap.policies.native.ToscaXacml + type_version: 1.0.0 + properties: + policies: + - properties: + description: Policy that allows minimum number of available cells for + a slice to be feasible, prio=1 + rules: + - condition: + apply: + keys: + - feasibleCellsForSlice + operator: integ + compareWith: + value: 2 + decision: Permit + advice: + value: Slice is feasible since minumum number of cells are available + metadata: + policy-id: bad.tosca.policy.test.1 + policy-version: 1.0.0 + name: bad.tosca.policy.test + version: 3.0.0 + metadata: + action: sfc-policy + description: This policy set specifies the conditions for slice feasibility + based on availability of cells + policy-id: tnap.policy.slice.sfc.set + policy-version: 3.0.0 +name: ToscaServiceTemplateSimple +version: 1.0.0 diff --git a/applications/native/src/test/resources/policies/native.toscapolicy.yaml b/applications/native/src/test/resources/policies/native.toscapolicy.yaml new file mode 100644 index 00000000..d4858366 --- /dev/null +++ b/applications/native/src/test/resources/policies/native.toscapolicy.yaml @@ -0,0 +1,1324 @@ +--- +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + inputs: {} + policies: + - tosca.policy.test: + type: onap.policies.native.ToscaXacml + type_version: 1.0.0 + properties: + policies: + - properties: + description: Policy that allows minimum number of available cells for a slice to + be feasible, prio=1 + combiningAlgo: first-applicable + target: + anyOne: + - allOf: + - key: action-id + operator: string-less-than + value: "1" + - allOf: + - key: action-id + operator: string-ends-with + value: "2" + - allOf: + - key: action-id + operator: time-greater-than-or-equal + value: "19:00:00 05:00" + - allOf: + - key: action-id + operator: string-less-than + value: "4" + - allOf: + - key: action-id + operator: yearmonthduration-one-and-only + value: "P16Y" + - allOf: + - key: action-id + operator: boolean-equal + value: "1" + rules: + - target: + anyOne: + - allOf: + - key: action-id + operator: string-equal-ignore-case + value: "1" + - allOf: + - key: action-id + operator: string-starts-with + value: "1" + - allOf: + - key: action-id + operator: time-greater-than + value: "19:00:00 05:00" + - allOf: + - key: action-id + operator: daytimeduration-one-and-only + value: "1" + - allOf: + - key: action-id + operator: double-equal + value: "1" + description : Policy that allows minimum number of available cells for a slice to + condition: + apply: + keys: + - feasibleCellsForSlice + - apply: + operator: string-is-in + keys: + - apply: + operator: double-divide + keys: + - function: any-of + - apply: + operator: double-divide + keys: + - feasibleCellsForSlice + - apply: + operator: integer-mod + keys: + - totalCellsForSlice + - "'100'" + - apply: + keys: + - function: string-less-than-or-equal + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + keys: + - function: string-greater-than-or-equal + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + keys: + - function: any-of-any + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + keys: + - function: string-less-than-or-equal + - "'90'" + operator: yearMonthDuration-equal + compareWith: + value: "30" + apply: + keys: + - "'90'" + operator: anyURI-equal + compareWith: + value: "30" + - apply: + keys: + - function: hexBinary-equal + - total-resource-usage-UL + operator: hexBinary-equal + compareWith: + value: "30" + apply: + keys: + - "'90'" + operator: rfc822Name-equal + compareWith: + value: "30" + - apply: + keys: + - function: any-of-any + - "'90'" + operator: x500Name-equal + compareWith: + value: "30" + apply: + keys: + - "'90'" + operator: string-from-ipAddress + compareWith: + value: "30" + - apply: + keys: + - function: string-less-than-or-equal + - "'90'" + operator: string-from-dnsName + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + keys: + - function: string-greater-than-or-equal + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + keys: + - function: any-of-any + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + operator: time-equal + keys: + - apply: + operator: datetime-equal + keys: + - apply: + operator: daytimeduration-equal + keys: + - "19:00:00 05:00" + - apply: + operator: base64binary-equal + keys: + - 100 + - "'100'" + - apply: + keys: + - function: string-normalize-space + - total-resource-usage-UL + operator: round + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: floor + compareWith: + value: "30" + - apply: + operator: string-normalize-to-lower-case + keys: + - apply: + operator: time-one-and-only + keys: + - apply: + operator: double-to-integer + keys: + - 02 + - apply: + operator: present + keys: + - 30 + - "'100'" + - apply: + keys: + - function: time-in-range + - total-resource-usage-UL + operator: double-add + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: string-bag-size + compareWith: + value: "30" + - apply: + operator: boolean-bag-size + keys: + - apply: + operator: integer-bag-size + keys: + - apply: + operator: double-bag-size + keys: + - "'30'" + - apply: + operator: time-bag-size + keys: + - "19:00:00 05:00" + - "'100'" + - apply: + keys: + - function: time-is-in + - total-resource-usage-UL + operator: time-bag + compareWith: + value: "19:00:00 05:00" + apply: + keys: + - "'30'" + operator: date-bag-size + compareWith: + value: "30" + - apply: + operator: rfc822name-is-in + keys: + - apply: + operator: rfc822name-bag + keys: + - apply: + operator: ipaddress-one-and-only + keys: + - "'30'" + - apply: + operator: ipaddress-bag-size + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: ipaddress-is-in + - "'30'" + operator: ipaddress-bag + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: dnsname-one-and-only + compareWith: + value: "30" + - apply: + operator: dnsname-bag-size + keys: + - apply: + operator: dnsname-is-in + keys: + - apply: + operator: dnsname-bag + keys: + - "'30'" + - apply: + operator: string-concatenate + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: boolean-from-string + - "'30'" + operator: string-from-boolean + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: integer-from-string + compareWith: + value: "30" + - apply: + operator: string-from-integer + keys: + - apply: + operator: double-from-string + keys: + - apply: + operator: string-from-double + keys: + - "'30'" + - apply: + operator: time-from-string + keys: + - "19:00:00 05:00" + - "'100'" + - apply: + keys: + - function: time-is-in + - "19:00:00 05:00" + operator: time-bag + compareWith: + value: "19:00:00 05:00" + apply: + keys: + - "'30'" + operator: date-bag-size + compareWith: + value: "30" + - apply: + operator: date-is-in + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: date-bag + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: anyuri-from-string + keys: + - apply: + operator: string-from-anyuri + keys: + - feasibleCellsForSlice + - apply: + operator: daytimeduration-from-string + keys: + - 100 + - "'100'" + - apply: + keys: + - function: string-from-daytimeturation + - "19:00:00 05:00" + operator: yearmonthduration-from-string + compareWith: + value: "P16Y" + apply: + keys: + - total-resource-usage-DL + operator: string-from-yearmonthduration + compareWith: + value: "P16Y" + - apply: + operator: x500name-from-string + keys: + - apply: + operator: string-from-x500name + keys: + - apply: + operator: rfc822name-from-string + keys: + - 02 + - apply: + operator: string-from-rfc822name + keys: + - 30 + - "'100'" + - apply: + keys: + - function: dnsname-from-string + - "'30'" + operator: anyuri-starts-with + compareWith: + value: "30" + apply: + keys: + - "'100'" + operator: anyuri-ends-with + compareWith: + value: "30" + - apply: + operator: anyuri-contains + keys: + - apply: + operator: string-substring + keys: + - apply: + operator: anyuri-substring + keys: + - "'30'" + - apply: + operator: map + keys: + - "'30'" + - "'100'" + - apply: + operator: ipaddress-from-string + keys: + - apply: + operator: double-intersection + keys: + - apply: + operator: anyuri-subset + keys: + - "'30'" + - apply: + operator: base64binary-at-least-one-member-of + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: x500name-match + - "'30'" + operator: rfc822name-match + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: anyuri-regexp-match + compareWith: + value: "30" + - apply: + operator: ipaddress-regexp-match + keys: + - apply: + operator: dnsname-regexp-match + keys: + - apply: + operator: rfc822name-regexp-match + keys: + - "'30'" + - apply: + operator: x500name-regexp-match + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: xpath-node-count + - "'30'" + operator: xpath-node-equal + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: xpath-node-match + compareWith: + value: "30" + - apply: + operator: string-intersection + keys: + - apply: + operator: string-at-least-one-member-of + keys: + - apply: + operator: string-union + keys: + - "'30'" + - apply: + operator: string-subset + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: string-set-equals + - "'30'" + operator: boolean-intersection + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: boolean-at-least-one-member-of + compareWith: + value: "30" + - apply: + operator: boolean-union + keys: + - apply: + operator: boolean-subset + keys: + - apply: + operator: boolean-set-equals + keys: + - "'30'" + - apply: + operator: integer-intersection + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: integer-at-least-one-member-of + - "'30'" + operator: integer-union + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: integer-subset + compareWith: + value: "30" + - apply: + operator: integer-set-equals + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: double-intersection + - apply: + operator: double-at-least-one-member-of + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + operator: string-equal + compareWith: + value: "2" + decision: Deny + advice: + value: Slice is feasible since minumum number of cells are available + default: Deny + metadata: + policy-id: tosca.policy.test.1 + policy-version: 1.0.0 + - properties: + description: Policy that allows minimum percentage of available cells for a + slice to be feasible, prio=2 + rules: + - target: + anyOne: + - allOf: + - key: sst + operator: integer-greater-than + value: "1" + - allOf: + - key: sst + operator: string-greater-than + value: "1" + - allOf: + - key: sst + operator: date-add-yearmonthduration + value: "P16Y" + - allOf: + - key: sst + operator: time-less-than + value: "19:00:00 05:00" + - allOf: + - key: sst + operator: hexbinary-one-and-only + value: "1" + - allOf: + - key: sst + operator: datetime-bag-size + value: "1" + - allOf: + - key: sst + operator: double-union + value: "1" + condition: + apply: + operator: double-greater-than-or-equal + keys: + - apply: + operator: double-multiply + keys: + - function: all-of-any + - apply: + operator: double-divide + keys: + - apply: + operator: integer-to-double + keys: + - feasibleCellsForSlice + - apply: + operator: integer-to-double + keys: + - totalCellsForSlice + - "'100'" + - apply: + keys: + - function: integer-greater-than-or-equal + - total-resource-usage-UL + operator: integer-less-than + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: integer-less-than + compareWith: + value: "30" + - apply: + operator: integer-is-in + keys: + - function: all-of-all + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: boolean-is-in + keys: + - function: all-of + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: integer-divide + keys: + - apply: + operator: double-divide + keys: + - apply: + operator: double-divide + keys: + - feasibleCellsForSlice + - apply: + operator: integer-mod + keys: + - totalCellsForSlice + - "'100'" + - apply: + keys: + - function: string-less-than-or-equal + - total-resource-usage-UL + operator: integer-abs + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-abs + compareWith: + value: "30" + - apply: + operator: string-contains + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: string-regexp-match + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: datetime-subtract-daytimeturation + keys: + - function: not + - apply: + operator: datetime-add-yearmonthduration + keys: + - apply: + operator: datetime-add-daytimeduration + keys: + - "P16Y" + - apply: + operator: double-less-than-or-equal + keys: + - totalCellsForSlice + - "'100'" + - apply: + keys: + - function: string-equal + - total-resource-usage-UL + operator: double-less-than + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: double-greater-than + compareWith: + value: "30" + - apply: + operator: integer-less-than-or-equal + keys: + - function: n-of + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: integer-equal + keys: + - function: and + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: date-less-than + keys: + - apply: + operator: date-greater-than-or-equal + keys: + - function: or + - apply: + operator: date-greater-than + keys: + - feasibleCellsForSlice + - apply: + operator: datetime-less-than-or-equal + keys: + - totalCellsForSlice + - "'100'" + - apply: + keys: + - function: datetime-less-than + - total-resource-usage-UL + operator: datetime-greater-than-or-equal + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: datetime-greater-than + compareWith: + value: "30" + - apply: + operator: boolean-bag + keys: + - function: any-of-all + - list: + - jkjd + - lll + - "'90'" + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: integer-bag + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: datetime-one-and-only + keys: + - apply: + operator: time-one-and-only + keys: + - apply: + operator: integer-multiply + keys: + - feasibleCellsForSlice + - apply: + operator: double-subtract + keys: + - totalCellsForSlice + - "19:00:00 05:00" + - apply: + keys: + - function: integer-subtract + - total-resource-usage-UL + operator: double-add + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: integer-add + compareWith: + value: "30" + - apply: + operator: double-is-in + keys: + - list: + - jkjd + - lll + - 90 + - "'89'" + compareWith: + key: total-resource-usage-UL + - apply: + operator: string-is-in + keys: + - list: + - jkjd + - lll + - "'90'" + - "'89'" + - apply: + operator: base64binary-union + keys: + - apply: + operator: base64binary-subset + keys: + - apply: + operator: base64binary-set-equals + keys: + - "'100'" + - apply: + operator: daytimeduration-intersection + keys: + - 100 + - "'100'" + - apply: + keys: + - function: daytimeduration-at-least-one-member-of + - total-resource-usage-UL + operator: daytimeduration-union + compareWith: + value: "30" + apply: + keys: + - total-resource-usage-DL + operator: daytimeduration-subset + compareWith: + value: "30" + - apply: + operator: daytimeduration-set-equals + keys: + - apply: + operator: yearmonthduration-intersection + keys: + - apply: + operator: yearmonthduration-at-least-one-member-of + keys: + - 02 + - apply: + operator: yearmonthduration-union + keys: + - 30 + - "'100'" + - apply: + keys: + - function: yearmonthduration-subset + - "'30'" + operator: yearmonthduration-set-equals + compareWith: + value: "30" + apply: + keys: + - "'100'" + operator: x500name-intersection + compareWith: + value: "30" + - apply: + operator: x500name-at-least-one-member-of + keys: + - apply: + operator: x500name-union + keys: + - apply: + operator: x500name-subset + keys: + - "'30'" + - apply: + operator: x500name-set-equals + keys: + - "'30'" + - "'100'" + - apply: + operator: rfc822name-intersection + keys: + - apply: + operator: rfc822name-at-least-one-member-of + keys: + - apply: + operator: rfc822name-union + keys: + - "'30'" + - apply: + operator: rfc822name-subset + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: rfc822name-set-equals + - "'30'" + operator: ipaddress-intersection + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: ipaddress-at-least-one-member-of + compareWith: + value: "30" + - apply: + operator: ipaddress-union + keys: + - apply: + operator: ipaddress-subset + keys: + - apply: + operator: ipaddress-set-equals + keys: + - "'30'" + - apply: + operator: dnsname-intersection + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: dnsname-at-least-one-member-of + - "'30'" + operator: dnsname-union + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: dnsname-subset + compareWith: + value: "30" + - apply: + operator: dnsname-set-equals + keys: + - apply: + operator: access-permitted + keys: + - apply: + operator: string-union + keys: + - "'30'" + - apply: + operator: string-subset + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: string-set-equals + - "'30'" + operator: boolean-intersection + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: boolean-at-least-one-member-of + compareWith: + value: "30" + - apply: + operator: boolean-union + keys: + - apply: + operator: boolean-subset + keys: + - apply: + operator: boolean-set-equals + keys: + - "'30'" + - apply: + operator: integer-intersection + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: integer-at-least-one-member-of + - "'30'" + operator: integer-union + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: integer-subset + compareWith: + value: "30" + - apply: + operator: datetime-one-and-only + keys: + - apply: + operator: datetime-bag + keys: + - apply: + operator: anyuri-bag-size + keys: + - "'30'" + - apply: + operator: anyuri-is-in + keys: + - "'30'" + - "19:00:00 05:00" + - apply: + keys: + - function: anyuri-bag + - "'30'" + operator: hexbinary-bag-size + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: hexbinary-is-in + compareWith: + value: "30" + - apply: + operator: hexbinary-bag + keys: + - apply: + operator: base64binary-bag-size + keys: + - apply: + operator: base64binary-is-in + keys: + - "'30'" + - apply: + operator: base64binary-bag + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: daytimeduration-bag-size + - "'30'" + operator: daytimeduration-is-in + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: daytimeduration-bag + compareWith: + value: "30" + - apply: + operator: yearmonthduration-bag-size + keys: + - apply: + operator: yearmonthduration-is-in + keys: + - apply: + operator: yearmonthduration-bag + keys: + - "'30'" + - apply: + operator: x500name-one-and-only + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: x500name-bag-size + - "'30'" + operator: x500name-is-in + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: x500name-bag + compareWith: + value: "30" + - apply: + operator: rfc822name-bag-size + keys: + - apply: + operator: string-from-time + keys: + - apply: + operator: date-from-string + keys: + - "'30'" + - apply: + operator: string-from-date + keys: + - "'30'" + - apply: + keys: + - "'30'" + operator: rfc822name-one-and-only + compareWith: + value: "30" + - apply: + operator: double-set-equals + keys: + - apply: + operator: time-intersection + keys: + - apply: + operator: time-at-least-one-member-of + keys: + - "19:00:00 05:00" + - apply: + operator: time-union + keys: + - "19:00:00 05:00" + - "'100'" + - apply: + keys: + - function: time-subset + - "'30'" + operator: time-set-equals + compareWith: + value: "19:00:00 05:00" + apply: + keys: + - "'30'" + operator: date-intersection + compareWith: + value: "30" + - apply: + operator: date-at-least-one-member-of + keys: + - apply: + operator: date-union + keys: + - apply: + operator: date-subset + keys: + - "'30'" + - apply: + operator: date-set-equals + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: datetime-intersection + - "'30'" + operator: datetime-at-least-one-member-of + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: datetime-union + compareWith: + value: "30" + - apply: + operator: datetime-subset + keys: + - apply: + operator: datetime-set-equals + keys: + - apply: + operator: anyuri-intersection + keys: + - "'30'" + - apply: + operator: anyuri-at-least-one-member-of + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: anyuri-union + - "'30'" + operator: anyuri-set-equals + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: hexbinary-intersection + compareWith: + value: "30" + - apply: + operator: hexbinary-at-least-one-member-of + keys: + - apply: + operator: hexbinary-union + keys: + - apply: + operator: hexbinary-subset + keys: + - "'30'" + - apply: + operator: hexbinary-set-equals + keys: + - "'30'" + - apply: + keys: + - "'30'" + operator: base64binary-intersection + compareWith: + value: "30" + - apply: + operator: datetime-subtract-yearmonthduration + keys: + - apply: + operator: date-subtract-yearmonthduration + keys: + - apply: + operator: time-less-than-or-equal + keys: + - "19:00:00 05:00" + - apply: + operator: date-less-than-or-equal + keys: + - "'30'" + - "'100'" + - apply: + operator: date-equal + keys: + - apply: + operator: datetime-is-in + keys: + - apply: + operator: datetime-from-string + keys: + - "'30'" + - apply: + operator: string-from-datetime + keys: + - "'30'" + - "'100'" + - apply: + keys: + - function: double-subset + - "'30'" + operator: base64binary-one-and-only + compareWith: + value: "30" + apply: + keys: + - "'30'" + operator: hexbinary-intersection + compareWith: + value: "30" + compareWith: + value: "50" + decision: Permit + advice: + value: Slice is feasible since minimum percentage of cells is available + default: Permit + metadata: + policy-id: tosca.policy.test.2 + policy-version: 1.0.0 + name: tosca.policy.test + version: 2.0.0 + metadata: + action: sfc-policy + description: This policy set specifies the conditions for slice feasibility + based on availability of cells + policy-id: tosca.policy.test + policy-version: 2.0.0 +name: ToscaServiceTemplateSimple +version: 1.0.0 diff --git a/main/src/test/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManagerTest.java b/main/src/test/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManagerTest.java index e4a61d53..f1ac0942 100644 --- a/main/src/test/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManagerTest.java +++ b/main/src/test/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManagerTest.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020-2022 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2024 Nordix Foundation. + * Modifications Copyright (C) 2024 Deutsche Telekom AG. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -144,10 +145,10 @@ class XacmlPdpApplicationManagerTest { // assertThat(manager).isNotNull(); assertThat(manager.getPolicyCount()).isZero(); - assertThat(manager.getPolicyTypeCount()).isEqualTo(18); + assertThat(manager.getPolicyTypeCount()).isEqualTo(19); assertThat(manager.getToscaPolicies()).isEmpty(); assertThat(manager.getToscaPolicyIdentifiers()).isEmpty(); - assertThat(manager.getToscaPolicyTypeIdents()).hasSize(18); + assertThat(manager.getToscaPolicyTypeIdents()).hasSize(19); assertThat(manager.findNativeApplication()).isInstanceOf(NativePdpApplication.class); |