* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import com.att.research.xacml.api.Response;
import com.att.research.xacml.api.Result;
import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
import com.att.research.xacml.std.annotations.RequestParser;
+import com.google.gson.annotations.SerializedName;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
+import lombok.Getter;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
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.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 oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.common.parameters.annotations.Valid;
import org.onap.policy.models.decisions.concepts.DecisionRequest;
import org.onap.policy.models.decisions.concepts.DecisionResponse;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
//
public static final String FIELD_BLACKLIST = "blacklist";
+ //
+ // filter property fields
+ //
+ public static final String FIELD_FILTER_WHITELIST = "whitelist";
+ public static final String FIELD_FILTER_ALGORITHM = "algorithm";
+ public static final String FIELD_FILTER_FILTERS = "filters";
+ public static final String FIELD_FILTER_FIELD = "field";
+ public static final String FIELD_FILTER_FUNCTION = "function";
+ public static final String FIELD_FILTER_FILTER = "filter";
+ public static final String FIELD_FILTER_BLACKLIST = "blacklist";
+
public static final String POLICYTYPE_FREQUENCY = "onap.policies.controlloop.guard.common.FrequencyLimiter";
public static final String POLICYTYPE_MINMAX = "onap.policies.controlloop.guard.common.MinMax";
public static final String POLICYTYPE_BLACKLIST = "onap.policies.controlloop.guard.common.Blacklist";
+ public static final String POLICYTYPE_FILTER = "onap.policies.controlloop.guard.common.Filter";
+
+ //
+ // Variable definitions
+ //
+ private static final String VARIABLE_TIMEINRANGE = "timeInRange";
public GuardTranslator() {
super();
/**
* Convert the policy.
*/
- public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
+ @Override
+ public Object convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
//
// Policy name should be at the root
//
//
// Set it as the policy ID
//
- PolicyType newPolicyType = new PolicyType();
+ var newPolicyType = new PolicyType();
newPolicyType.setPolicyId(policyName);
//
// Optional description
//
this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata());
//
+ // There should be properties metadata section
+ //
+ if (toscaPolicy.getProperties() == null) {
+ throw new ToscaPolicyConversionException("no properties specified on guard policy: " + policyName);
+ }
+ //
// Generate the TargetType - add true if not blacklist
//
newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties(),
} else if (POLICYTYPE_BLACKLIST.equals(toscaPolicy.getType())) {
newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_PERMIT_UNLESS_DENY.stringValue());
generateBlacklistRules(toscaPolicy, policyName, newPolicyType);
+ } else if (POLICYTYPE_FILTER.equals(toscaPolicy.getType())) {
+ newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_PERMIT_UNLESS_DENY.stringValue());
+ generateFilterRules(toscaPolicy, policyName, newPolicyType);
} else {
throw new ToscaPolicyConversionException("Unknown guard policy type " + toscaPolicy.getType());
}
+ //
+ // Add in our variable definition
+ //
+ VariableReferenceType variable = this.createTimeRangeVariable(toscaPolicy.getProperties(), newPolicyType);
+ if (variable != null) {
+ //
+ // Update all the rules to have conditions for this variable
+ //
+ this.addVariableToConditionTypes(variable, newPolicyType);
+ }
return newPolicyType;
}
+ /**
+ * This method iterates through all the existing rules, adding in a conditionType that will test
+ * whether the Variable is true or false. Any existing ConditionType will be updated to AND with the
+ * Variable.
+ *
+ * @param variable VariableDefinitionType to add
+ * @param newPolicyType PolicyType that will be updated
+ */
+ private void addVariableToConditionTypes(VariableReferenceType variable,
+ PolicyType newPolicyType) {
+ //
+ // Iterate through the rules
+ //
+ for (Object objectType : newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
+ if (objectType instanceof RuleType) {
+ RuleType rule = (RuleType) objectType;
+ if (rule.getCondition() == null) {
+ //
+ // No condition already, just create and add a new one
+ //
+ var condition = new ConditionType();
+ condition.setExpression(new ObjectFactory().createVariableReference(variable));
+ rule.setCondition(condition);
+ } else {
+ //
+ // Need to create a new ConditionType that treats all the expressions as an AND
+ // with the Variable.
+ //
+ rule.setCondition(ToscaPolicyTranslatorUtils.addVariableToCondition(rule.getCondition(), variable,
+ XACML3.ID_FUNCTION_AND));
+ }
+ }
+ }
+ }
+
/**
* Convert Request.
*/
- public Request convertRequest(DecisionRequest request) {
+ @Override
+ public Request convertRequest(DecisionRequest request) throws ToscaPolicyConversionException {
LOGGER.info("Converting Request {}", request);
try {
return RequestParser.parseRequest(GuardPolicyRequest.createInstance(request));
} catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
- LOGGER.error("Failed to convert DecisionRequest", e);
+ throw new ToscaPolicyConversionException("Failed to convert DecisionRequest", e);
}
- //
- // TODO throw exception
- //
- return null;
}
/**
* Convert response.
*/
+ @Override
public DecisionResponse convertResponse(Response xacmlResponse) {
LOGGER.info("Converting Response {}", xacmlResponse);
- DecisionResponse decisionResponse = new DecisionResponse();
+ var decisionResponse = new DecisionResponse();
//
// Iterate through all the results
//
protected TargetType generateTargetType(Map<String, Object> properties, boolean addTargets)
throws ToscaPolicyConversionException {
//
+ // Decode the definition from the policy's properties
+ //
+ TargetTypeDefinition targetTypeDef =
+ ToscaPolicyTranslatorUtils.decodeProperties(properties, TargetTypeDefinition.class);
+ //
// Go through potential properties
//
- AllOfType allOf = new AllOfType();
- if (properties.containsKey(FIELD_ACTOR)) {
- addMatch(allOf, properties.get(FIELD_ACTOR), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
+ var allOf = new AllOfType();
+ if (targetTypeDef.getActor() != null) {
+ addMatch(allOf, targetTypeDef.getActor(), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR);
}
- if (properties.containsKey(FIELD_OPERATION)) {
- addMatch(allOf, properties.get(FIELD_OPERATION), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
+ if (targetTypeDef.getOperation() != null) {
+ addMatch(allOf, targetTypeDef.getOperation(), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE);
}
- if (addTargets && properties.containsKey(FIELD_TARGET)) {
- addMatch(allOf, properties.get(FIELD_TARGET), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
+ if (addTargets && targetTypeDef.getTarget() != null) {
+ addMatch(allOf, targetTypeDef.getTarget(), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
}
- if (properties.containsKey(FIELD_CONTROLLOOP)) {
- addMatch(allOf, properties.get(FIELD_CONTROLLOOP), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME);
- }
- if (properties.containsKey(FIELD_TIMERANGE)) {
- addTimeRangeMatch(allOf, properties.get(FIELD_TIMERANGE));
+ if (targetTypeDef.getId() != null) {
+ addMatch(allOf, targetTypeDef.getId(), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME);
}
//
// Create target
//
- TargetType target = new TargetType();
- AnyOfType anyOf = new AnyOfType();
+ var target = new TargetType();
+ var anyOf = new AnyOfType();
anyOf.getAllOf().add(allOf);
target.getAnyOf().add(anyOf);
return target;
//
// Exact match
//
- MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ var match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_STRING_EQUAL,
value,
XACML3.ID_DATATYPE_STRING,
}
if (value instanceof Collection) {
((Collection<String>) value).forEach(val -> {
- MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ var match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_STRING_EQUAL,
val,
XACML3.ID_DATATYPE_STRING,
return allOf;
}
- @SuppressWarnings("rawtypes")
- protected void addTimeRangeMatch(AllOfType allOf, Object timeRange)
+ protected void addTimeRangeMatch(AllOfType allOf, TimeRange timeRange)
throws ToscaPolicyConversionException {
- if (! (timeRange instanceof Map)) {
- throw new ToscaPolicyConversionException("timeRange is not a map object " + timeRange.getClass());
- }
- MatchType matchStart = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ var matchStart = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL,
- ((Map) timeRange).get("start_time").toString(),
+ timeRange.getStartTime(),
XACML3.ID_DATATYPE_TIME,
XACML3.ID_ENVIRONMENT_CURRENT_TIME,
- XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
+ XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);
allOf.getMatch().add(matchStart);
- MatchType matchEnd = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ var matchEnd = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL,
- ((Map) timeRange).get("end_time").toString(),
+ timeRange.getEndTime(),
XACML3.ID_DATATYPE_TIME,
XACML3.ID_ENVIRONMENT_CURRENT_TIME,
XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT);
allOf.getMatch().add(matchEnd);
}
- protected void generateFrequencyRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType)
+ protected VariableReferenceType createTimeRangeVariable(Map<String, Object> properties, PolicyType newPolicyType)
throws ToscaPolicyConversionException {
//
- // We must have the limit
+ // Decode the definition from the policy's properties
//
- if (! toscaPolicy.getProperties().containsKey(FIELD_LIMIT)) {
- throw new ToscaPolicyConversionException("Missing property limit");
+ TimeRangeDefinition timeRangeDef =
+ ToscaPolicyTranslatorUtils.decodeProperties(properties, TimeRangeDefinition.class);
+ TimeRange timeRange = timeRangeDef.getTimeRange();
+ if (timeRange == null) {
+ return null;
}
//
- // See if its possible to generate a count
+ // Should also be parseable as an ISO8601 timestamp
+ //
+ var startTimeObject = parseTimestamp(timeRange.getStartTime());
+ var endTimeObject = parseTimestamp(timeRange.getEndTime());
//
- Integer limit = ToscaPolicyTranslatorUtils.parseInteger(
- toscaPolicy.getProperties().get(FIELD_LIMIT).toString());
- if (limit == null) {
- throw new ToscaPolicyConversionException("Missing limit value");
+ // They should be the same object types. We cannot establish a range
+ // between an OffsetDateTime and an OffsetTime
+ //
+ if (! startTimeObject.getClass().equals(endTimeObject.getClass())) {
+ throw new ToscaPolicyConversionException("start_time and end_time class types do not match");
}
- String timeWindow = null;
- if (toscaPolicy.getProperties().containsKey(FIELD_TIMEWINDOW)) {
- Integer intTimeWindow = ToscaPolicyTranslatorUtils.parseInteger(
- toscaPolicy.getProperties().get(FIELD_TIMEWINDOW).toString());
- if (intTimeWindow == null) {
- throw new ToscaPolicyConversionException("timeWindow is not an integer");
- }
- timeWindow = intTimeWindow.toString();
+ //
+ // Create the inner timeInRange ApplyType
+ //
+ ApplyType timeInRange = ToscaPolicyTranslatorUtils.generateTimeInRange(timeRange.getStartTime(),
+ timeRange.getEndTime(), true);
+ var variable = new VariableDefinitionType();
+ variable.setVariableId(VARIABLE_TIMEINRANGE);
+ variable.setExpression(new ObjectFactory().createApply(timeInRange));
+ //
+ // Add it to the policy
+ //
+ newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(variable);
+ //
+ // Create and return the reference to the variable
+ //
+ var reference = new VariableReferenceType();
+ reference.setVariableId(variable.getVariableId());
+ return reference;
+ }
+
+ private Object parseTimestamp(String string) throws ToscaPolicyConversionException {
+ //
+ // First see if it is a full datetime object
+ //
+ try {
+ return OffsetDateTime.parse(string);
+ } catch (Exception e) {
+ LOGGER.warn("timestamp {} could not be parsed. This may not be an error.", string, e);
+ }
+ //
+ // May only be a time object
+ //
+ try {
+ return OffsetTime.parse(string);
+ } catch (Exception e) {
+ throw new ToscaPolicyConversionException("timestamp " + string + " could not be parsed ", e);
}
- String timeUnits = null;
- if (toscaPolicy.getProperties().containsKey(FIELD_TIMEUNITS)) {
- timeUnits = toscaPolicy.getProperties().get(FIELD_TIMEUNITS).toString();
+ }
+
+ protected void generateFrequencyRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType)
+ throws ToscaPolicyConversionException {
+ //
+ // Decode the definition from the policy's properties
+ //
+ FrequencyDefinition frequencyDef = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(),
+ FrequencyDefinition.class);
+ //
+ // See if its possible to generate a count
+ //
+ String timeWindow = null;
+ if (frequencyDef.getTimeWindow() != null) {
+ timeWindow = frequencyDef.getTimeWindow().toString();
}
//
// Generate a count
//
- final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits);
+ final ApplyType countCheck =
+ generateCountCheck(frequencyDef.getLimit(), timeWindow, frequencyDef.getTimeUnits());
//
// Create our condition
//
- final ConditionType condition = new ConditionType();
+ final var condition = new ConditionType();
condition.setExpression(new ObjectFactory().createApply(countCheck));
//
// Now we can create our rule
//
- RuleType frequencyRule = new RuleType();
+ var frequencyRule = new RuleType();
frequencyRule.setDescription("Frequency limit permit rule");
frequencyRule.setRuleId(policyName + ":frequency");
frequencyRule.setEffect(EffectType.PERMIT);
}
protected ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) {
- AttributeDesignatorType designator = new AttributeDesignatorType();
+ var designator = new AttributeDesignatorType();
designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT.stringValue());
designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
+ ":tw:" + timeWindow + ":" + timeUnits;
designator.setIssuer(issuer);
- AttributeValueType valueLimit = new AttributeValueType();
+ var valueLimit = new AttributeValueType();
valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue());
//
// Yes really use toString(), the marshaller will
//
valueLimit.getContent().add(limit.toString());
- ObjectFactory factory = new ObjectFactory();
+ var factory = new ObjectFactory();
- ApplyType applyOneAndOnly = new ApplyType();
+ var applyOneAndOnly = new ApplyType();
applyOneAndOnly.setDescription("Unbag the limit");
applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue());
applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator));
- ApplyType applyLessThan = new ApplyType();
+ var applyLessThan = new ApplyType();
applyLessThan.setDescription("return true if current count is less than.");
applyLessThan.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN.stringValue());
applyLessThan.getExpression().add(factory.createApply(applyOneAndOnly));
protected void generateMinMaxRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType)
throws ToscaPolicyConversionException {
//
+ // Decode the definition from the policy's properties
+ //
+ MinMaxDefinition minMaxDef = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(),
+ MinMaxDefinition.class);
+ //
// Add the target
//
- if (! toscaPolicy.getProperties().containsKey(FIELD_TARGET)) {
- throw new ToscaPolicyConversionException("Missing target field in minmax policy");
- }
- MatchType matchTarget = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ var matchTarget = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_STRING_EQUAL,
- toscaPolicy.getProperties().get(FIELD_TARGET).toString(),
+ minMaxDef.getTarget(),
XACML3.ID_DATATYPE_STRING,
ToscaDictionary.ID_RESOURCE_GUARD_TARGETID,
XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
// For the min, if the # of instances is less than the minimum
// then allow the scale.
//
- Integer min = null;
- if (toscaPolicy.getProperties().containsKey(FIELD_MIN)) {
- min = ToscaPolicyTranslatorUtils.parseInteger(toscaPolicy.getProperties().get(FIELD_MIN).toString());
- MatchType matchMin = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ if (minMaxDef.getMin() != null) {
+ var matchMin = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_INTEGER_GREATER_THAN,
- min.toString(),
+ minMaxDef.getMin().toString(),
XACML3.ID_DATATYPE_INTEGER,
ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT,
XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(
generateMinMaxRule(matchTarget, matchMin, policyName + ":minrule", "check minimum"));
}
- Integer max = null;
- if (toscaPolicy.getProperties().containsKey(FIELD_MAX)) {
- max = ToscaPolicyTranslatorUtils.parseInteger(toscaPolicy.getProperties().get(FIELD_MAX).toString());
- MatchType matchMax = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ if (minMaxDef.getMax() != null) {
+ var matchMax = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
XACML3.ID_FUNCTION_INTEGER_GREATER_THAN,
- max.toString(),
+ minMaxDef.getMax().toString(),
XACML3.ID_DATATYPE_INTEGER,
ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT,
XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
//
// Do we have at least a min or max?
//
- if (min == null && max == null) {
+ if (minMaxDef.getMin() == null && minMaxDef.getMax() == null) {
throw new ToscaPolicyConversionException("Missing min or max field in minmax policy");
}
}
protected RuleType generateMinMaxRule(MatchType matchTarget, MatchType matchMinOrMax, String ruleId, String desc) {
- AllOfType allOf = new AllOfType();
+ var allOf = new AllOfType();
allOf.getMatch().add(matchTarget);
allOf.getMatch().add(matchMinOrMax);
- AnyOfType anyOf = new AnyOfType();
+ var anyOf = new AnyOfType();
anyOf.getAllOf().add(allOf);
- TargetType target = new TargetType();
+ var target = new TargetType();
target.getAnyOf().add(anyOf);
- RuleType minMaxRule = new RuleType();
+ var minMaxRule = new RuleType();
minMaxRule.setEffect(EffectType.PERMIT);
minMaxRule.setDescription(desc);
minMaxRule.setRuleId(ruleId);
protected void generateBlacklistRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType)
throws ToscaPolicyConversionException {
//
- // Validate the blacklist exists
+ // Decode the definition from the policy's properties
+ //
+ BlacklistDefinition blacklistDef = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(),
+ BlacklistDefinition.class);
//
- if (! toscaPolicy.getProperties().containsKey(FIELD_BLACKLIST)) {
- throw new ToscaPolicyConversionException("Missing blacklist field");
+ // Iterate the entries and create individual AnyOf so each entry is
+ // treated as an OR.
+ //
+ var target = new TargetType();
+ var anyOf = new AnyOfType();
+ for (Object blacklisted : blacklistDef.blacklist) {
+ var allOf = new AllOfType();
+ this.addMatch(allOf, blacklisted, ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
+ anyOf.getAllOf().add(allOf);
}
- final AllOfType allOf = new AllOfType();
- this.addMatch(allOf, toscaPolicy.getProperties().get(FIELD_BLACKLIST),
- ToscaDictionary.ID_RESOURCE_GUARD_TARGETID);
+ target.getAnyOf().add(anyOf);
//
// Create our rule and add the target
//
- RuleType blacklistRule = new RuleType();
+ var blacklistRule = new RuleType();
blacklistRule.setEffect(EffectType.DENY);
blacklistRule.setDescription("blacklist the entities");
blacklistRule.setRuleId(policyName + ":blacklist");
- TargetType target = new TargetType();
- AnyOfType anyOf = new AnyOfType();
- anyOf.getAllOf().add(allOf);
- target.getAnyOf().add(anyOf);
blacklistRule.setTarget(target);
//
// Add the rule to the policy
newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(blacklistRule);
}
+ protected void generateFilterRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType)
+ throws ToscaPolicyConversionException {
+ //
+ // Decode the definition from the policy's properties
+ //
+ FilterDefinition filterDef = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(),
+ FilterDefinition.class);
+ //
+ // Set the combining algorithm
+ //
+ switch (filterDef.getAlgorithm()) {
+ case "whitelist-overrides":
+ newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_PERMIT_OVERRIDES.stringValue());
+ break;
+ case "blacklist-overrides":
+ newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_OVERRIDES.stringValue());
+ break;
+ default:
+ throw new ToscaPolicyConversionException(
+ "Unexpected value for algorithm, should be whitelist-overrides or blacklist-overrides");
+ }
+ //
+ // Iterate the filters
+ //
+ var ruleId = 1;
+ for (FilterAttribute filterAttributes : filterDef.filters) {
+ //
+ // Check fields requiring extra validation
+ //
+ String field = validateFilterPropertyField(filterAttributes.getField());
+ Identifier function = validateFilterPropertyFunction(filterAttributes.getFunction());
+ //
+ // Create our filter rule
+ //
+ RuleType filterRule = createFilterRule(policyName + ":rule" + ruleId++, field, filterAttributes.getFilter(),
+ function, filterAttributes.getBlacklist());
+ //
+ // Add the rule to the policy
+ //
+ newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(filterRule);
+ }
+ }
+
+ private String validateFilterPropertyField(String field)
+ throws ToscaPolicyConversionException {
+ String fieldLowerCase = field.toLowerCase();
+ switch (fieldLowerCase) {
+ case "generic-vnf.vnf-name":
+ case "generic-vnf.vnf-id":
+ case "generic-vnf.vnf-type":
+ case "generic-vnf.nf-naming-code":
+ case "vserver.vserver-id":
+ case "cloud-region.cloud-region-id":
+ return fieldLowerCase;
+ default:
+ throw new ToscaPolicyConversionException("Unexpected value for field in filter");
+ }
+ }
+
+ private Identifier validateFilterPropertyFunction(String function)
+ throws ToscaPolicyConversionException {
+ switch (function.toLowerCase()) {
+ case "string-equal":
+ return XACML3.ID_FUNCTION_STRING_EQUAL;
+ case "string-equal-ignore-case":
+ return XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE;
+ case "string-regexp-match":
+ return XACML3.ID_FUNCTION_STRING_REGEXP_MATCH;
+ case "string-contains":
+ return XACML3.ID_FUNCTION_STRING_CONTAINS;
+ case "string-greater-than":
+ return XACML3.ID_FUNCTION_STRING_GREATER_THAN;
+ case "string-greater-than-or-equal":
+ return XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL;
+ case "string-less-than":
+ return XACML3.ID_FUNCTION_STRING_LESS_THAN;
+ case "string-less-than-or-equal":
+ return XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL;
+ case "string-starts-with":
+ return XACML3.ID_FUNCTION_STRING_STARTS_WITH;
+ case "string-ends-with":
+ return XACML3.ID_FUNCTION_STRING_ENDS_WITH;
+ default:
+ throw new ToscaPolicyConversionException("Unexpected value for function in filter");
+ }
+ }
+
+ private RuleType createFilterRule(String ruleId, String field, String filter, Identifier function,
+ boolean isBlacklisted) {
+ var rule = new RuleType();
+ rule.setRuleId(ruleId);
+
+ //
+ // Create the Match
+ //
+ var matchFilter = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
+ function,
+ filter,
+ XACML3.ID_DATATYPE_STRING,
+ new IdentifierImpl(GuardPolicyRequest.PREFIX_RESOURCE_ATTRIBUTE_ID + field),
+ XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE
+ );
+ var allOf = new AllOfType();
+ allOf.getMatch().add(matchFilter);
+ var anyOf = new AnyOfType();
+ anyOf.getAllOf().add(allOf);
+ var target = new TargetType();
+ target.getAnyOf().add(anyOf);
+
+ rule.setTarget(target);
+
+ if (isBlacklisted) {
+ rule.setEffect(EffectType.DENY);
+ } else {
+ rule.setEffect(EffectType.PERMIT);
+ }
+ return rule;
+ }
+
+ @Getter
+ public static class TimeRangeDefinition {
+ private @Valid TimeRange timeRange;
+ }
+
+ @Getter
+ public static class TargetTypeDefinition {
+ private String actor;
+ private String operation;
+ private String target;
+ private String id;
+ }
+
+ @Getter
+ @NotNull
+ @NotBlank
+ public static class TimeRange {
+ @SerializedName("start_time")
+ private String startTime;
+
+ @SerializedName("end_time")
+ private String endTime;
+ }
+
+ @Getter
+ public static class FrequencyDefinition {
+ @NotNull
+ private Integer limit;
+ private Integer timeWindow;
+ private String timeUnits;
+ }
+
+ @Getter
+ public static class MinMaxDefinition {
+ @NotNull
+ private String target;
+ private Integer min;
+ private Integer max;
+ }
+
+ @Getter
+ @NotNull
+ public static class BlacklistDefinition {
+ private List<@NotNull Object> blacklist;
+ }
+
+ @Getter
+ @NotNull
+ public static class FilterDefinition {
+ private String algorithm;
+ private List<@NotNull @Valid FilterAttribute> filters;
+ }
+
+ @Getter
+ @NotNull
+ public static class FilterAttribute {
+ private String field;
+ private String filter;
+ private String function;
+ private Boolean blacklist;
+ }
}