diff options
Diffstat (limited to 'applications/guard/src/main')
-rw-r--r-- | applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java | 15 | ||||
-rw-r--r-- | applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java (renamed from applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java) | 27 | ||||
-rw-r--r-- | applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java | 505 | ||||
-rw-r--r-- | applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java | 786 |
4 files changed, 521 insertions, 812 deletions
diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java index 0073f74e..b4e431c4 100644 --- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java +++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,23 +42,22 @@ public class GuardPdpApplication extends StdXacmlApplicationServiceProvider { private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplication.class); private static final String STRING_VERSION100 = "1.0.0"; private List<ToscaPolicyTypeIdentifier> supportedPolicyTypes = new ArrayList<>(); - private LegacyGuardTranslator legacyTranslator = new LegacyGuardTranslator(); + private GuardTranslator guardTranslator = new GuardTranslator(); private CoordinationGuardTranslator coordinationTranslator = new CoordinationGuardTranslator(); - /** * Constructor. * */ public GuardPdpApplication() { this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.controlloop.guard.FrequencyLimiter", + GuardTranslator.POLICYTYPE_FREQUENCY, STRING_VERSION100)); this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.controlloop.guard.MinMax", + GuardTranslator.POLICYTYPE_MINMAX, STRING_VERSION100)); this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( - "onap.policies.controlloop.guard.Blacklist", + GuardTranslator.POLICYTYPE_BLACKLIST, STRING_VERSION100)); this.supportedPolicyTypes.add(new ToscaPolicyTypeIdentifier( "onap.policies.controlloop.guard.coordination.FirstBlocksSecond", @@ -101,8 +100,8 @@ public class GuardPdpApplication extends StdXacmlApplicationServiceProvider { LOGGER.debug("returning coordinationTranslator"); return coordinationTranslator; } else { - LOGGER.debug("returning legacyTranslator"); - return legacyTranslator; + LOGGER.debug("returning guardTranslator"); + return guardTranslator; } } diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java index bfbe4f64..51d8f0ed 100644 --- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java +++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ import org.onap.policy.models.decisions.concepts.DecisionRequest; @Setter @ToString @XACMLRequest(ReturnPolicyIdList = true) -public class LegacyGuardPolicyRequest { +public class GuardPolicyRequest { private static final String STR_GUARD = "guard"; @@ -73,14 +73,7 @@ public class LegacyGuardPolicyRequest { @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:vf-count") private Integer vfCount; - @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:min") - private Integer min; - - @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:max") - private Integer max; - - - public LegacyGuardPolicyRequest() { + public GuardPolicyRequest() { super(); } @@ -91,11 +84,11 @@ public class LegacyGuardPolicyRequest { * @return StdMetadataPolicyRequest */ @SuppressWarnings("unchecked") - public static LegacyGuardPolicyRequest createInstance(DecisionRequest decisionRequest) { + public static GuardPolicyRequest createInstance(DecisionRequest decisionRequest) { // // Create our return object // - LegacyGuardPolicyRequest request = new LegacyGuardPolicyRequest(); + GuardPolicyRequest request = new GuardPolicyRequest(); // // Add the subject attributes // @@ -140,14 +133,12 @@ public class LegacyGuardPolicyRequest { request.targetId = guard.get("target").toString(); } if (guard.containsKey("vfCount")) { + // + // TODO this can potentially throw a NumberFormatException. Fix this to + // throw the exception when you fix the ConvertRequest to throw exceptions also. + // request.vfCount = Integer.decode(guard.get("vfCount").toString()); } - if (guard.containsKey("min")) { - request.min = Integer.decode(guard.get("min").toString()); - } - if (guard.containsKey("max")) { - request.max = Integer.decode(guard.get("max").toString()); - } return request; } diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java new file mode 100644 index 00000000..ebcae8dd --- /dev/null +++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java @@ -0,0 +1,505 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.xacml.pdp.application.guard; + +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Decision; +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.Result; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.annotations.RequestParser; +import java.util.Collection; +import java.util.Map; +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.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.EffectType; +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.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.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils; +import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GuardTranslator implements ToscaPolicyTranslator { + private static final Logger LOGGER = LoggerFactory.getLogger(GuardTranslator.class); + + // + // common guard property fields + // + public static final String FIELD_ACTOR = "actor"; + public static final String FIELD_OPERATION = "operation"; + public static final String FIELD_CONTROLLOOP = "id"; + public static final String FIELD_TIMERANGE = "timeRange"; + + // + // frequency property fields + // + public static final String FIELD_TIMEWINDOW = "timeWindow"; + public static final String FIELD_TIMEUNITS = "timeUnits"; + public static final String FIELD_LIMIT = "limit"; + + // + // minmax property fields + // + public static final String FIELD_TARGET = "target"; + public static final String FIELD_MIN = "min"; + public static final String FIELD_MAX = "max"; + + // + // blacklist property fields + // + public static final String FIELD_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 GuardTranslator() { + super(); + } + + /** + * Convert the policy. + */ + public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { + // + // Policy name should be at the root + // + String policyName = toscaPolicy.getMetadata().get("policy-id"); + // + // Set it as the policy ID + // + PolicyType newPolicyType = new PolicyType(); + newPolicyType.setPolicyId(policyName); + // + // Optional description + // + newPolicyType.setDescription(toscaPolicy.getDescription()); + // + // There should be a metadata section + // + this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata()); + // + // Generate the TargetType - add true if not blacklist + // + newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties(), + ! POLICYTYPE_BLACKLIST.equals(toscaPolicy.getType()))); + // + // Add specific's per guard policy type + // + if (POLICYTYPE_FREQUENCY.equals(toscaPolicy.getType())) { + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue()); + generateFrequencyRules(toscaPolicy, policyName, newPolicyType); + } else if (POLICYTYPE_MINMAX.equals(toscaPolicy.getType())) { + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue()); + generateMinMaxRules(toscaPolicy, policyName, newPolicyType); + } else if (POLICYTYPE_BLACKLIST.equals(toscaPolicy.getType())) { + newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_PERMIT_UNLESS_DENY.stringValue()); + generateBlacklistRules(toscaPolicy, policyName, newPolicyType); + } else { + throw new ToscaPolicyConversionException("Unknown guard policy type " + toscaPolicy.getType()); + } + return newPolicyType; + } + + /** + * Convert Request. + */ + public Request convertRequest(DecisionRequest request) { + LOGGER.info("Converting Request {}", request); + try { + return RequestParser.parseRequest(GuardPolicyRequest.createInstance(request)); + } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) { + LOGGER.error("Failed to convert DecisionRequest: {}", e); + } + // + // TODO throw exception + // + return null; + } + + /** + * Convert response. + */ + public DecisionResponse convertResponse(Response xacmlResponse) { + LOGGER.info("Converting Response {}", xacmlResponse); + DecisionResponse decisionResponse = new DecisionResponse(); + // + // Iterate through all the results + // + for (Result xacmlResult : xacmlResponse.getResults()) { + // + // Check the result + // + if (xacmlResult.getDecision() == Decision.PERMIT) { + // + // Just simply return a Permit response + // + decisionResponse.setStatus(Decision.PERMIT.toString()); + } else if (xacmlResult.getDecision() == Decision.DENY) { + // + // Just simply return a Deny response + // + decisionResponse.setStatus(Decision.DENY.toString()); + } else { + // + // There is no guard policy, so we return a permit + // + decisionResponse.setStatus(Decision.PERMIT.toString()); + } + } + + return decisionResponse; + } + + /** + * From the TOSCA metadata section, pull in values that are needed into the XACML policy. + * + * @param policy Policy Object to store the metadata + * @param map The Metadata TOSCA Map + * @return Same Policy Object + */ + protected PolicyType fillMetadataSection(PolicyType policy, Map<String, String> map) { + // + // NOTE: The models code ensures the metadata section ALWAYS exists + // + // + // Add in the Policy Version + // + policy.setVersion(map.get("policy-version")); + return policy; + } + + /** + * Generate the targettype for the policy. Optional to add MatchType for the target. eg. the + * blacklist policy type uses the target in a different manner. + * + * @param properties TOSCA properties object + * @param addTargets true to go ahead and add target to the match list. + * @return TargetType object + * @throws ToscaPolicyConversionException if there is a missing property + */ + protected TargetType generateTargetType(Map<String, Object> properties, boolean addTargets) + throws ToscaPolicyConversionException { + // + // Go through potential properties + // + AllOfType allOf = new AllOfType(); + if (properties.containsKey(FIELD_ACTOR)) { + addMatch(allOf, properties.get(FIELD_ACTOR), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR); + } + if (properties.containsKey(FIELD_OPERATION)) { + addMatch(allOf, properties.get(FIELD_OPERATION), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE); + } + if (addTargets && properties.containsKey(FIELD_TARGET)) { + addMatch(allOf, properties.get(FIELD_TARGET), 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)); + } + // + // Create target + // + TargetType target = new TargetType(); + AnyOfType anyOf = new AnyOfType(); + anyOf.getAllOf().add(allOf); + target.getAnyOf().add(anyOf); + return target; + } + + @SuppressWarnings("unchecked") + protected AllOfType addMatch(AllOfType allOf, Object value, Identifier attributeId) { + if (value instanceof String) { + if (".*".equals(value.toString())) { + // + // There's no point to even have a match + // + return allOf; + } else { + // + // Exact match + // + MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + value, + XACML3.ID_DATATYPE_STRING, + attributeId, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + + allOf.getMatch().add(match); + } + return allOf; + } + if (value instanceof Collection) { + ((Collection<String>) value).forEach(val -> { + MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + val, + XACML3.ID_DATATYPE_STRING, + attributeId, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + + allOf.getMatch().add(match); + }); + } + return allOf; + } + + @SuppressWarnings("rawtypes") + protected void addTimeRangeMatch(AllOfType allOf, Object timeRange) + throws ToscaPolicyConversionException { + if (! (timeRange instanceof Map)) { + throw new ToscaPolicyConversionException("timeRange is not a map object " + timeRange.getClass()); + } + + MatchType matchStart = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, + ((Map) timeRange).get("start_time").toString(), + XACML3.ID_DATATYPE_TIME, + XACML3.ID_ENVIRONMENT_CURRENT_TIME, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + + allOf.getMatch().add(matchStart); + + MatchType matchEnd = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, + ((Map) timeRange).get("end_time").toString(), + 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) + throws ToscaPolicyConversionException { + // + // We must have the limit + // + if (! toscaPolicy.getProperties().containsKey(FIELD_LIMIT)) { + throw new ToscaPolicyConversionException("Missing property limit"); + } + // + // See if its possible to generate a count + // + Integer limit = ToscaPolicyTranslatorUtils.parseInteger( + toscaPolicy.getProperties().get(FIELD_LIMIT).toString()); + if (limit == null) { + throw new ToscaPolicyConversionException("Missing limit value"); + } + 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(); + } + String timeUnits = null; + if (toscaPolicy.getProperties().containsKey(FIELD_TIMEUNITS)) { + timeUnits = toscaPolicy.getProperties().get(FIELD_TIMEUNITS).toString(); + } + // + // Generate a count + // + final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits); + // + // Create our condition + // + final ConditionType condition = new ConditionType(); + condition.setExpression(new ObjectFactory().createApply(countCheck)); + + // + // Now we can create our rule + // + RuleType frequencyRule = new RuleType(); + frequencyRule.setDescription("Frequency limit permit rule"); + frequencyRule.setRuleId(policyName + ":frequency"); + frequencyRule.setEffect(EffectType.PERMIT); + frequencyRule.setTarget(new TargetType()); + // + // Add the condition + // + frequencyRule.setCondition(condition); + // + // Add the rule to the policy + // + newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(frequencyRule); + } + + protected ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) { + AttributeDesignatorType 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()); + // + // Setup issuer - used by the operations PIP to determine + // how to do the database query. + // + String issuer = ToscaDictionary.GUARD_ISSUER_PREFIX + + CountRecentOperationsPip.ISSUER_NAME + + ":tw:" + timeWindow + ":" + timeUnits; + designator.setIssuer(issuer); + + AttributeValueType valueLimit = new AttributeValueType(); + valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); + // + // Yes really use toString(), the marshaller will + // throw an exception if this is an integer object + // and not a string. + // + valueLimit.getContent().add(limit.toString()); + + ObjectFactory factory = new ObjectFactory(); + + ApplyType 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(); + 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)); + applyLessThan.getExpression().add(factory.createAttributeValue(valueLimit)); + + return applyLessThan; + } + + protected void generateMinMaxRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType) + throws ToscaPolicyConversionException { + // + // Add the target + // + if (! toscaPolicy.getProperties().containsKey(FIELD_TARGET)) { + throw new ToscaPolicyConversionException("Missing target field in minmax policy"); + } + MatchType matchTarget = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( + XACML3.ID_FUNCTION_STRING_EQUAL, + toscaPolicy.getProperties().get(FIELD_TARGET).toString(), + 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( + XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, + min.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( + XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, + max.toString(), + XACML3.ID_DATATYPE_INTEGER, + ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT, + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); + + newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add( + generateMinMaxRule(matchTarget, matchMax, policyName + ":maxrule", "check maximum")); + } + // + // Do we have at least a min or max? + // + if (min == null && max == 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(); + allOf.getMatch().add(matchTarget); + allOf.getMatch().add(matchMinOrMax); + AnyOfType anyOf = new AnyOfType(); + anyOf.getAllOf().add(allOf); + TargetType target = new TargetType(); + target.getAnyOf().add(anyOf); + RuleType minMaxRule = new RuleType(); + minMaxRule.setEffect(EffectType.PERMIT); + minMaxRule.setDescription(desc); + minMaxRule.setRuleId(ruleId); + minMaxRule.setTarget(target); + return minMaxRule; + } + + protected void generateBlacklistRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType) + throws ToscaPolicyConversionException { + // + // Validate the blacklist exists + // + if (! toscaPolicy.getProperties().containsKey(FIELD_BLACKLIST)) { + throw new ToscaPolicyConversionException("Missing blacklist field"); + } + final AllOfType allOf = new AllOfType(); + this.addMatch(allOf, toscaPolicy.getProperties().get(FIELD_BLACKLIST), + ToscaDictionary.ID_RESOURCE_GUARD_TARGETID); + // + // Create our rule and add the target + // + RuleType 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); + } + +} diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java deleted file mode 100644 index 0cb06ea0..00000000 --- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java +++ /dev/null @@ -1,786 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.xacml.pdp.application.guard; - -import com.att.research.xacml.api.DataTypeException; -import com.att.research.xacml.api.Decision; -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.Result; -import com.att.research.xacml.api.XACML3; -import com.att.research.xacml.std.annotations.RequestParser; - -import java.util.Collection; -import java.util.Map; - -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.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.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.EffectType; -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.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.models.decisions.concepts.DecisionRequest; -import org.onap.policy.models.decisions.concepts.DecisionResponse; -import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; -import org.onap.policy.pdp.xacml.application.common.ToscaDictionary; -import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; -import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator; -import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils; -import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LegacyGuardTranslator implements ToscaPolicyTranslator { - - private static final Logger LOGGER = LoggerFactory.getLogger(LegacyGuardTranslator.class); - - private static final String FIELD_GUARD_ACTIVE_START = "guardActiveStart"; - private static final String FIELD_GUARD_ACTIVE_END = "guardActiveEnd"; - private static final String FIELD_TARGET = "targets"; - private static final String DESC_DEFAULT = "Default is to PERMIT if the policy matches."; - private static final String ID_RULE = ":rule"; - - public LegacyGuardTranslator() { - super(); - } - - @Override - public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException { - // - // Policy name should be at the root - // - String policyName = toscaPolicy.getMetadata().get("policy-id"); - // - // Set it as the policy ID - // - PolicyType newPolicyType = new PolicyType(); - newPolicyType.setPolicyId(policyName); - // - // Optional description - // - newPolicyType.setDescription(toscaPolicy.getDescription()); - // - // There should be a metadata section - // - this.fillMetadataSection(newPolicyType, toscaPolicy.getMetadata()); - // - // Set the combining rule - // - newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue()); - // - // Generate the TargetType - add true if not blacklist - // - newPolicyType.setTarget(this.generateTargetType(toscaPolicy.getProperties(), - ! "onap.policies.controlloop.guard.Blacklist".equals(toscaPolicy.getType()))); - // - // Now create the Permit Rule - // - RuleType rule = generatePermitRule(policyName, toscaPolicy.getType(), toscaPolicy.getProperties()); - // - // Check if we were able to create the rule - // - if (rule == null) { - LOGGER.error("Failed to create rule"); - return null; - } - // - // Add the rule to the policy - // - newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule); - // - // Return our new policy - // - return newPolicyType; - } - - @Override - public Request convertRequest(DecisionRequest request) { - LOGGER.info("Converting Request {}", request); - try { - return RequestParser.parseRequest(LegacyGuardPolicyRequest.createInstance(request)); - } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) { - LOGGER.error("Failed to convert DecisionRequest: {}", e); - } - // - // TODO throw exception - // - return null; - } - - @Override - public DecisionResponse convertResponse(Response xacmlResponse) { - LOGGER.info("Converting Response {}", xacmlResponse); - DecisionResponse decisionResponse = new DecisionResponse(); - // - // Iterate through all the results - // - for (Result xacmlResult : xacmlResponse.getResults()) { - // - // Check the result - // - if (xacmlResult.getDecision() == Decision.PERMIT) { - // - // Just simply return a Permit response - // - decisionResponse.setStatus(Decision.PERMIT.toString()); - } - if (xacmlResult.getDecision() == Decision.DENY) { - // - // Just simply return a Deny response - // - decisionResponse.setStatus(Decision.DENY.toString()); - } - if (xacmlResult.getDecision() == Decision.NOTAPPLICABLE) { - // - // There is no guard policy, so we return a permit - // - decisionResponse.setStatus(Decision.PERMIT.toString()); - } - } - - return decisionResponse; - } - - /** - * From the TOSCA metadata section, pull in values that are needed into the XACML policy. - * - * @param policy Policy Object to store the metadata - * @param map The Metadata TOSCA Map - * @return Same Policy Object - * @throws ToscaPolicyConversionException If there is something missing from the metadata - */ - protected PolicyType fillMetadataSection(PolicyType policy, - Map<String, String> map) throws ToscaPolicyConversionException { - if (! map.containsKey("policy-id")) { - throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-id"); - } else { - // - // Do nothing here - the XACML PolicyId is used from TOSCA Policy Name field - // - } - if (! map.containsKey("policy-version")) { - throw new ToscaPolicyConversionException(policy.getPolicyId() + " missing metadata policy-version"); - } else { - // - // Add in the Policy Version - // - policy.setVersion(map.get("policy-version")); - } - return policy; - } - - protected TargetType generateTargetType(Map<String, Object> properties, boolean addTargets) { - // - // Go through potential properties - // - AllOfType allOf = new AllOfType(); - if (properties.containsKey("actor")) { - addMatch(allOf, properties.get("actor"), ToscaDictionary.ID_RESOURCE_GUARD_ACTOR); - } - if (properties.containsKey("recipe")) { - addMatch(allOf, properties.get("recipe"), ToscaDictionary.ID_RESOURCE_GUARD_RECIPE); - } - if (addTargets && properties.containsKey(FIELD_TARGET)) { - addMatch(allOf, properties.get(FIELD_TARGET), ToscaDictionary.ID_RESOURCE_GUARD_TARGETID); - } - if (properties.containsKey("clname")) { - addMatch(allOf, properties.get("clname"), ToscaDictionary.ID_RESOURCE_GUARD_CLNAME); - } - // - // Create target - // - TargetType target = new TargetType(); - AnyOfType anyOf = new AnyOfType(); - anyOf.getAllOf().add(allOf); - target.getAnyOf().add(anyOf); - return target; - } - - private static AllOfType addMatch(AllOfType allOf, Object value, Identifier attributeId) { - if (value instanceof String) { - if (".*".equals(value.toString())) { - // - // There's no point to even have a match - // - return allOf; - } else { - // - // Exact match - // - MatchType match = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator( - XACML3.ID_FUNCTION_STRING_EQUAL, - value, - XACML3.ID_DATATYPE_STRING, - attributeId, - XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE); - - allOf.getMatch().add(match); - } - return allOf; - } - if (value instanceof Collection) { - // - // TODO support a collection of that attribute - // - } - return allOf; - } - - private static RuleType generatePermitRule(String policyName, String policyType, Map<String, Object> properties) - throws ToscaPolicyConversionException { - // - // Now determine which policy type we are generating - // - if ("onap.policies.controlloop.guard.FrequencyLimiter".equals(policyType)) { - return generateFrequencyPermit(policyName, properties); - } else if ("onap.policies.controlloop.guard.MinMax".equals(policyType)) { - return generateMinMaxPermit(policyName, properties); - } else if ("onap.policies.controlloop.guard.Blacklist".equals(policyType)) { - return generateBlacklistPermit(policyName, properties); - } - LOGGER.error("Missing policy type in the policy"); - return null; - } - - private static RuleType generateFrequencyPermit(String policyName, Map<String, Object> properties) - throws ToscaPolicyConversionException { - // - // See if its possible to generate a count - // - Integer limit = parseInteger(properties.get("limit").toString()); - if (limit == null) { - LOGGER.error("Must have a limit value for frequency guard policy to be created"); - return null; - } - // - // Get the properties that are common among guards - // - String timeWindow = null; - if (properties.containsKey("timeWindow")) { - Integer intTimeWindow = parseInteger(properties.get("timeWindow").toString()); - if (intTimeWindow == null) { - throw new ToscaPolicyConversionException("timeWindow is not an integer"); - } - timeWindow = intTimeWindow.toString(); - } - String timeUnits = null; - if (properties.containsKey("timeUnits")) { - timeUnits = properties.get("timeUnits").toString(); - } - String guardActiveStart = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) { - guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString(); - } - String guardActiveEnd = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) { - guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString(); - } - // - // Generate the time in range - // - final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd); - // - // Generate a count - // - final ApplyType countCheck = generateCountCheck(limit, timeWindow, timeUnits); - // - // Now combine into an And - // - ApplyType applyAnd = new ApplyType(); - applyAnd.setDescription("return true if time range and count checks are true."); - applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue()); - applyAnd.getExpression().add(new ObjectFactory().createApply(timeRange)); - applyAnd.getExpression().add(new ObjectFactory().createApply(countCheck)); - - // - // Create our condition - // - final ConditionType condition = new ConditionType(); - condition.setExpression(new ObjectFactory().createApply(applyAnd)); - - // - // Now we can create our rule - // - RuleType permit = new RuleType(); - permit.setDescription(DESC_DEFAULT); - permit.setRuleId(policyName + ID_RULE); - permit.setEffect(EffectType.PERMIT); - permit.setTarget(new TargetType()); - // - // Add the condition - // - permit.setCondition(condition); - // - // Done - // - return permit; - } - - private static RuleType generateMinMaxPermit(String policyName, Map<String, Object> properties) { - // - // Get the properties that are common among guards - // - String guardActiveStart = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) { - guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString(); - } - String guardActiveEnd = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) { - guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString(); - } - // - // Generate the time in range - // - final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd); - // - // See if its possible to generate a count - // - Integer min = null; - if (properties.containsKey("min")) { - min = parseInteger(properties.get("min").toString()); - } - Integer max = null; - if (properties.containsKey("max")) { - max = parseInteger(properties.get("max").toString()); - } - final ApplyType minApply = generateMinCheck(min); - final ApplyType maxApply = generateMaxCheck(max); - // - // Make sure we have at least something to check here, - // otherwise there really is no point to this policy. - // - if (timeRange == null && minApply == null && maxApply == null) { - return null; - } - // - // Create our rule - // - RuleType permit = new RuleType(); - permit.setDescription(DESC_DEFAULT); - permit.setRuleId(policyName + ID_RULE); - permit.setEffect(EffectType.PERMIT); - permit.setTarget(new TargetType()); - // - // Create the condition - // - permit.setCondition(createCondition(timeRange, minApply, maxApply)); - // - // Done - // - return permit; - } - - private static ConditionType createCondition(ApplyType timeRange, ApplyType minApply, ApplyType maxApply) { - final ConditionType condition = new ConditionType(); - // - // Check if we have all the fields (this can be a little - // ugly) but the ultimate goal is to simplify the policy - // condition to only check for necessary attributes. - // - ObjectFactory factory = new ObjectFactory(); - if (timeRange != null && minApply != null && maxApply != null) { - // - // All 3 must apply - // - ApplyType applyAnd = new ApplyType(); - applyAnd.setDescription("return true if all the apply's are true."); - applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue()); - applyAnd.getExpression().add(factory.createApply(timeRange)); - applyAnd.getExpression().add(factory.createApply(minApply)); - applyAnd.getExpression().add(factory.createApply(maxApply)); - // - // Add into the condition - // - condition.setExpression(factory.createApply(applyAnd)); - - return condition; - } - // - // At least one of these applies is null. We need at least - // two to require the And apply. Otherwise there is no need - // for an outer And apply as the single condition can work - // on its own. - // - if (timeRange != null && minApply == null && maxApply == null) { - // - // Only the time range check is necessary - // - condition.setExpression(factory.createApply(timeRange)); - } else if (timeRange == null && minApply != null && maxApply == null) { - // - // Only the min check is necessary - // - condition.setExpression(factory.createApply(minApply)); - } else if (timeRange == null && minApply == null) { - // - // Only the max check is necessary - // - condition.setExpression(factory.createApply(maxApply)); - } else { - // - // Ok we will need an outer And and have at least the - // time range and either min or max check - // - ApplyType applyAnd = new ApplyType(); - applyAnd.setDescription("return true if all the apply's are true."); - applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue()); - if (timeRange != null) { - applyAnd.getExpression().add(factory.createApply(timeRange)); - } - if (minApply != null) { - applyAnd.getExpression().add(factory.createApply(minApply)); - } - if (maxApply != null) { - applyAnd.getExpression().add(factory.createApply(maxApply)); - } - // - // Add into the condition - // - condition.setExpression(factory.createApply(applyAnd)); - } - return condition; - } - - private static RuleType generateBlacklistPermit(String policyName, Map<String, Object> properties) { - // - // Generate target - // - if (! properties.containsKey(FIELD_TARGET)) { - LOGGER.error("Missing target for blacklist policy"); - return null; - } - final ApplyType targetApply = generateTargetApply(properties.get(FIELD_TARGET)); - // - // Get the properties that are common among guards - // - String guardActiveStart = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_START)) { - guardActiveStart = properties.get(FIELD_GUARD_ACTIVE_START).toString(); - } - String guardActiveEnd = null; - if (properties.containsKey(FIELD_GUARD_ACTIVE_END)) { - guardActiveEnd = properties.get(FIELD_GUARD_ACTIVE_END).toString(); - } - // - // Generate the time in range - // - final ApplyType timeRange = generateTimeInRange(guardActiveStart, guardActiveEnd); - // - // Create our rule - // - RuleType permit = new RuleType(); - permit.setDescription(DESC_DEFAULT); - permit.setRuleId(policyName + ID_RULE); - permit.setEffect(EffectType.PERMIT); - permit.setTarget(new TargetType()); - // - // Create our condition - // - ObjectFactory factory = new ObjectFactory(); - ApplyType innerApply; - if (timeRange != null) { - ApplyType applyAnd = new ApplyType(); - applyAnd.setDescription("Combine the timeRange with target to create AND"); - applyAnd.setFunctionId(XACML3.ID_FUNCTION_AND.stringValue()); - applyAnd.getExpression().add(factory.createApply(timeRange)); - applyAnd.getExpression().add(factory.createApply(targetApply)); - // - // Now we need to NOT this so the permit happens - // - ApplyType applyNot = new ApplyType(); - applyNot.setDescription("This should be false for a permit."); - applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue()); - applyNot.getExpression().add(factory.createApply(applyAnd)); - innerApply = applyNot; - } else { - // - // Just the target is needed - // - ApplyType applyNot = new ApplyType(); - applyNot.setDescription("This should be false for a permit."); - applyNot.setFunctionId(XACML3.ID_FUNCTION_NOT.stringValue()); - applyNot.getExpression().add(factory.createApply(targetApply)); - innerApply = applyNot; - } - // - // Create our condition - // - final ConditionType condition = new ConditionType(); - // - // Add into the condition - // - condition.setExpression(factory.createApply(innerApply)); - // - // Add the condition - // - permit.setCondition(condition); - return permit; - } - - private static ApplyType generateTimeInRange(String start, String end) { - if (start == null || end == null) { - LOGGER.warn("Missing time range start {} end {}", start, end); - return null; - } - if (start.isEmpty() || end.isEmpty()) { - LOGGER.warn("Empty time range start {} end {}", start, end); - return null; - } - - AttributeDesignatorType designator = new AttributeDesignatorType(); - designator.setAttributeId(XACML3.ID_ENVIRONMENT_CURRENT_TIME.stringValue()); - designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ENVIRONMENT.stringValue()); - designator.setDataType(XACML3.ID_DATATYPE_TIME.stringValue()); - - AttributeValueType valueStart = new AttributeValueType(); - valueStart.setDataType(XACML3.ID_DATATYPE_TIME.stringValue()); - valueStart.getContent().add(start); - - AttributeValueType valueEnd = new AttributeValueType(); - valueEnd.setDataType(XACML3.ID_DATATYPE_TIME.stringValue()); - valueEnd.getContent().add(end); - - ObjectFactory factory = new ObjectFactory(); - - ApplyType applyOneAndOnly = new ApplyType(); - applyOneAndOnly.setDescription("Unbag the current time"); - applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY.stringValue()); - applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator)); - - ApplyType applyTimeInRange = new ApplyType(); - applyTimeInRange.setDescription("return true if current time is in range."); - applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue()); - applyTimeInRange.getExpression().add(factory.createApply(applyOneAndOnly)); - applyTimeInRange.getExpression().add(factory.createAttributeValue(valueStart)); - applyTimeInRange.getExpression().add(factory.createAttributeValue(valueEnd)); - - return applyTimeInRange; - } - - private static ApplyType generateCountCheck(Integer limit, String timeWindow, String timeUnits) { - AttributeDesignatorType 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()); - // - // Setup issuer - // - String issuer = ToscaDictionary.GUARD_ISSUER_PREFIX - + CountRecentOperationsPip.ISSUER_NAME - + ":tw:" + timeWindow + ":" + timeUnits; - designator.setIssuer(issuer); - - AttributeValueType valueLimit = new AttributeValueType(); - valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); - // - // Yes really use toString(), the marshaller will - // throw an exception if this is an integer object - // and not a string. - // - valueLimit.getContent().add(limit.toString()); - - ObjectFactory factory = new ObjectFactory(); - - ApplyType 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(); - 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)); - applyLessThan.getExpression().add(factory.createAttributeValue(valueLimit)); - - return applyLessThan; - } - - private static ApplyType generateMinCheck(Integer min) { - if (min == null) { - return null; - } - AttributeDesignatorType designator = new AttributeDesignatorType(); - designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue()); - designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue()); - designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); - // - // - // - AttributeValueType valueLimit = new AttributeValueType(); - valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); - // - // Yes really use toString(), the marshaller will - // throw an exception if this is an integer object - // and not a string. - // - valueLimit.getContent().add(min.toString()); - ObjectFactory factory = new ObjectFactory(); - - ApplyType applyOneAndOnly = new ApplyType(); - applyOneAndOnly.setDescription("Unbag the min"); - applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue()); - applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator)); - - ApplyType applyGreaterThanEqual = new ApplyType(); - applyGreaterThanEqual.setDescription("return true if current count is greater than or equal."); - applyGreaterThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL.stringValue()); - applyGreaterThanEqual.getExpression().add(factory.createApply(applyOneAndOnly)); - applyGreaterThanEqual.getExpression().add(factory.createAttributeValue(valueLimit)); - - return applyGreaterThanEqual; - } - - private static ApplyType generateMaxCheck(Integer max) { - if (max == null) { - return null; - } - AttributeDesignatorType designator = new AttributeDesignatorType(); - designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.stringValue()); - designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue()); - designator.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); - // - // - // - AttributeValueType valueLimit = new AttributeValueType(); - valueLimit.setDataType(XACML3.ID_DATATYPE_INTEGER.stringValue()); - // - // Yes really use toString(), the marshaller will - // throw an exception if this is an integer object - // and not a string. - // - valueLimit.getContent().add(max.toString()); - ObjectFactory factory = new ObjectFactory(); - - ApplyType applyOneAndOnly = new ApplyType(); - applyOneAndOnly.setDescription("Unbag the min"); - applyOneAndOnly.setFunctionId(XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY.stringValue()); - applyOneAndOnly.getExpression().add(factory.createAttributeDesignator(designator)); - - ApplyType applyLessThanEqual = new ApplyType(); - applyLessThanEqual.setDescription("return true if current count is less than or equal."); - applyLessThanEqual.setFunctionId(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL.stringValue()); - applyLessThanEqual.getExpression().add(factory.createApply(applyOneAndOnly)); - applyLessThanEqual.getExpression().add(factory.createAttributeValue(valueLimit)); - - return applyLessThanEqual; - } - - @SuppressWarnings("unchecked") - private static ApplyType generateTargetApply(Object targetObject) { - ObjectFactory factory = new ObjectFactory(); - // - // Create a bag of values - // - ApplyType applyStringBag = new ApplyType(); - applyStringBag.setDescription("Bag the target values"); - applyStringBag.setFunctionId(XACML3.ID_FUNCTION_STRING_BAG.stringValue()); - if (targetObject instanceof Collection) { - for (Object target : ((Collection<Object>) targetObject)) { - if (! (target instanceof String)) { - LOGGER.error("Collection of unsupported objects {}", target.getClass()); - return null; - } - AttributeValueType value = new AttributeValueType(); - value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); - value.getContent().add(target.toString()); - applyStringBag.getExpression().add(factory.createAttributeValue(value)); - } - } else if (targetObject instanceof String) { - AttributeValueType value = new AttributeValueType(); - value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); - value.getContent().add(targetObject.toString()); - applyStringBag.getExpression().add(factory.createAttributeValue(value)); - } else { - LOGGER.warn("Unsupported object for target {}", targetObject.getClass()); - return null; - } - // - // Create our designator - // - AttributeDesignatorType designator = new AttributeDesignatorType(); - designator.setAttributeId(ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.stringValue()); - designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue()); - designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); - // - // Create apply for our AnyOf - // - ApplyType applyAnyOf = new ApplyType(); - applyAnyOf.setDescription("Find designator as anyof the possible values"); - applyAnyOf.setFunctionId(XACML3.ID_FUNCTION_ANY_OF.stringValue()); - applyAnyOf.getExpression().add(factory.createAttributeDesignator(designator)); - applyAnyOf.getExpression().add(factory.createApply(applyStringBag)); - return applyAnyOf; - } - - private static Integer parseInteger(String strInteger) { - Integer theInt = null; - try { - theInt = Integer.parseInt(strInteger); - } catch (NumberFormatException e) { - LOGGER.warn("Expecting an integer", e); - try { - Double dblLimit = Double.parseDouble(strInteger); - theInt = dblLimit.intValue(); - } catch (NumberFormatException e1) { - LOGGER.error("Failed to parse expected integer as a double", e); - return null; - } - } - return theInt; - } - - @SuppressWarnings("unused") - private static AdviceExpressionsType generateRequestIdAdvice() { - AdviceExpressionType adviceExpression = new AdviceExpressionType(); - adviceExpression.setAppliesTo(EffectType.PERMIT); - adviceExpression.setAdviceId(ToscaDictionary.ID_ADVICE_GUARD.stringValue()); - - AttributeDesignatorType designator = new AttributeDesignatorType(); - designator.setAttributeId(ToscaDictionary.ID_SUBJECT_GUARD_REQUESTID.stringValue()); - designator.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue()); - designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue()); - - AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType(); - assignment.setAttributeId(ToscaDictionary.ID_ADVICE_GUARD_REQUESTID.stringValue()); - assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue()); - assignment.setExpression(new ObjectFactory().createAttributeDesignator(designator)); - - adviceExpression.getAttributeAssignmentExpression().add(assignment); - - AdviceExpressionsType adviceExpressions = new AdviceExpressionsType(); - adviceExpressions.getAdviceExpression().add(adviceExpression); - - return adviceExpressions; - } -} |