Added tosca xacml policy type in Native Application 20/139020/3
authorajinkya-patil <ajinkya-patil@t-systems.com>
Tue, 24 Sep 2024 06:54:42 +0000 (12:24 +0530)
committerAjinkya Patil <ajinkya-patil@t-systems.com>
Thu, 17 Oct 2024 09:48:50 +0000 (09:48 +0000)
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>
applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplication.java
applications/native/src/main/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTranslator.java
applications/native/src/test/java/org/onap/policy/xacml/pdp/application/nativ/NativePdpApplicationTest.java
applications/native/src/test/resources/policies/bad.native.tosca.policy.target.yaml [new file with mode: 0644]
applications/native/src/test/resources/policies/bad.native.toscapolicy.yaml [new file with mode: 0644]
applications/native/src/test/resources/policies/native.toscapolicy.yaml [new file with mode: 0644]
main/src/test/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManagerTest.java

index cfe1a71..b6eeb52 100644 (file)
@@ -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
index 3caf28f..5e87f22 100644 (file)
@@ -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.
 
 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
index 47e92c0..04fe1fe 100644 (file)
@@ -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 (file)
index 0000000..2d2d966
--- /dev/null
@@ -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 (file)
index 0000000..d19f085
--- /dev/null
@@ -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 (file)
index 0000000..d485836
--- /dev/null
@@ -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
index e4a61d5..f1ac094 100644 (file)
@@ -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);