diff options
Diffstat (limited to 'applications/guard')
8 files changed, 306 insertions, 11 deletions
diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java index 87635963..7394ab30 100644 --- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.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-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 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. @@ -23,9 +23,14 @@ package org.onap.policy.xacml.pdp.application.guard; import com.att.research.xacml.std.annotations.XACMLAction; +import com.att.research.xacml.std.annotations.XACMLEnvironment; import com.att.research.xacml.std.annotations.XACMLRequest; import com.att.research.xacml.std.annotations.XACMLResource; import com.att.research.xacml.std.annotations.XACMLSubject; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZoneOffset; import java.util.Map; import lombok.Getter; import lombok.Setter; @@ -55,6 +60,20 @@ public class GuardPolicyRequest { @XACMLAction private String action = STR_GUARD; + @XACMLEnvironment(includeInResults = true, + attributeId = "urn:oasis:names:tc:xacml:1.0:environment:current-dateTime") + private OffsetDateTime currentDateTime; + + @XACMLEnvironment(includeInResults = true, attributeId = "urn:oasis:names:tc:xacml:1.0:environment:current-date") + private LocalDate currentDate; + + @XACMLEnvironment(includeInResults = true, attributeId = "urn:oasis:names:tc:xacml:1.0:environment:current-time") + private OffsetTime currentTime; + + @XACMLEnvironment(includeInResults = true, attributeId = "urn:org:onap:guard:timezone", + datatype = "urn:com:att:research:datatype:zone-offset") + private ZoneOffset timeZone; + @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:clname:clname-id") private String clnameId; @@ -115,6 +134,10 @@ public class GuardPolicyRequest { request.onapComponent = decisionRequest.getOnapComponent(); request.onapInstance = decisionRequest.getOnapInstance(); request.requestId = decisionRequest.getRequestId(); + request.currentDateTime = decisionRequest.getCurrentDateTime(); + request.currentDate = decisionRequest.getCurrentDate(); + request.currentTime = decisionRequest.getCurrentTime(); + request.timeZone = decisionRequest.getTimeZone(); // // Now pull from the resources // 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 index ddb9bb07..fd9bb004 100644 --- 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 @@ -32,6 +32,8 @@ 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 java.time.OffsetDateTime; +import java.time.OffsetTime; import java.util.Collection; import java.util.Map; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; @@ -46,6 +48,9 @@ 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 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.apache.commons.lang3.StringUtils; 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; @@ -103,6 +108,11 @@ public class GuardTranslator implements ToscaPolicyTranslator { 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(); } @@ -158,10 +168,56 @@ public class GuardTranslator implements ToscaPolicyTranslator { } else { throw new ToscaPolicyConversionException("Unknown guard policy type " + toscaPolicy.getType()); } + // + // Add in our variable definition + // + Object timeRange = toscaPolicy.getProperties().get(FIELD_TIMERANGE); + if (timeRange != null) { + VariableReferenceType variable = this.createTimeRangeVariable(timeRange, newPolicyType); + // + // 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 + // + ConditionType 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. */ @Override @@ -254,9 +310,6 @@ public class GuardTranslator implements ToscaPolicyTranslator { 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 // @@ -331,6 +384,81 @@ public class GuardTranslator implements ToscaPolicyTranslator { allOf.getMatch().add(matchEnd); } + @SuppressWarnings("rawtypes") + protected VariableReferenceType createTimeRangeVariable(Object timeRange, PolicyType newPolicyType) + throws ToscaPolicyConversionException { + // + // Sanity check the properties + // + if (! (timeRange instanceof Map)) { + throw new ToscaPolicyConversionException("timeRange is not a map object " + timeRange.getClass()); + } + String startTimestamp; + String endTimestamp; + try { + startTimestamp = ((Map) timeRange).get("start_time").toString(); + endTimestamp = ((Map) timeRange).get("end_time").toString(); + if (StringUtils.isBlank(startTimestamp)) { + throw new ToscaPolicyConversionException("Missing timeRange start_time property"); + } + if (StringUtils.isBlank(endTimestamp)) { + throw new ToscaPolicyConversionException("Missing timeRange end_time property"); + } + } catch (ToscaPolicyConversionException e) { + throw e; + } catch (Exception e) { + throw new ToscaPolicyConversionException("Invalid timeRange", e); + } + // + // Should also be parseable as an ISO8601 timestamp + // + Object startTimeObject = parseTimestamp(startTimestamp); + Object endTimeObject = parseTimestamp(endTimestamp); + // + // 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"); + } + // + // Create the inner timeInRange ApplyType + // + ApplyType timeInRange = ToscaPolicyTranslatorUtils.generateTimeInRange(startTimestamp, endTimestamp, true); + VariableDefinitionType 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 + // + VariableReferenceType 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); + } + } + protected void generateFrequencyRules(ToscaPolicy toscaPolicy, String policyName, PolicyType newPolicyType) throws ToscaPolicyConversionException { // diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java index 3b1b1c60..5b32b2a8 100644 --- a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2021 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.sql.Date; import java.time.Instant; +import java.time.OffsetDateTime; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -426,6 +427,67 @@ public class GuardPdpApplicationTest { requestAndCheckDecision(requestVfCount, PERMIT); } + @Test + public void test7TimeInRange() throws Exception { + LOGGER.info("**************** Running test7TimeInRange ****************"); + // + // Re-Load Decision Request - so we can start from scratch + // + DecisionRequest requestInRange = + gson.decode(TextFileUtils.getTextFileAsString("src/test/resources/requests/guard.timeinrange.json"), + DecisionRequest.class); + // + // Load the test policy in with the others. + // + List<ToscaPolicy> loadedPolicies = + TestUtils.loadPolicies("src/test/resources/test-time-in-range.yaml", service); + assertThat(loadedPolicies).hasSize(1); + // + // Mock what the current date and time is. Set to 12 Noon + // We actually do not care about time zone or the date yet, but these are here + // for future. + // + OffsetDateTime offsetDateTime = OffsetDateTime.parse("2020-01-01T12:00:00+05:00"); + requestInRange.setCurrentDateTime(offsetDateTime); + requestInRange.setCurrentDate(offsetDateTime.toLocalDate()); + requestInRange.setCurrentTime(offsetDateTime.toOffsetTime()); + requestInRange.setTimeZone(offsetDateTime.getOffset()); + + requestAndCheckDecision(requestInRange, PERMIT); + + offsetDateTime = OffsetDateTime.parse("2020-01-01T07:59:59+05:00"); + requestInRange.setCurrentDateTime(offsetDateTime); + requestInRange.setCurrentDate(offsetDateTime.toLocalDate()); + requestInRange.setCurrentTime(offsetDateTime.toOffsetTime()); + requestInRange.setTimeZone(offsetDateTime.getOffset()); + + requestAndCheckDecision(requestInRange, DENY); + + offsetDateTime = OffsetDateTime.parse("2020-01-01T08:00:00+05:00"); + requestInRange.setCurrentDateTime(offsetDateTime); + requestInRange.setCurrentDate(offsetDateTime.toLocalDate()); + requestInRange.setCurrentTime(offsetDateTime.toOffsetTime()); + requestInRange.setTimeZone(offsetDateTime.getOffset()); + + requestAndCheckDecision(requestInRange, PERMIT); + + offsetDateTime = OffsetDateTime.parse("2020-01-01T23:59:59+05:00"); + requestInRange.setCurrentDateTime(offsetDateTime); + requestInRange.setCurrentDate(offsetDateTime.toLocalDate()); + requestInRange.setCurrentTime(offsetDateTime.toOffsetTime()); + requestInRange.setTimeZone(offsetDateTime.getOffset()); + + requestAndCheckDecision(requestInRange, PERMIT); + + offsetDateTime = OffsetDateTime.parse("2020-01-01T00:00:00+05:00"); + requestInRange.setCurrentDateTime(offsetDateTime); + requestInRange.setCurrentDate(offsetDateTime.toLocalDate()); + requestInRange.setCurrentTime(offsetDateTime.toOffsetTime()); + requestInRange.setTimeZone(offsetDateTime.getOffset()); + + requestAndCheckDecision(requestInRange, DENY); + } + @SuppressWarnings("unchecked") private void insertOperationEvent(DecisionRequest request) { // diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java index e4c958b9..cf8c0158 100644 --- a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java @@ -2,7 +2,7 @@ * ============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"); @@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.att.research.xacml.api.Decision; import com.att.research.xacml.api.Request; -import com.att.research.xacml.api.XACML3; import com.att.research.xacml.std.StdMutableResponse; import com.att.research.xacml.std.StdMutableResult; import com.att.research.xacml.std.StdStatus; @@ -43,6 +42,7 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType; 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.VariableDefinitionType; import org.junit.Test; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.coder.StandardYamlCoder; @@ -119,6 +119,9 @@ public class GuardTranslatorTest { final Map<String, String> name2message = new HashMap<>(); name2message.put("frequency-missing-properties", "Missing property limit"); name2message.put("frequency-timewindow", "timeWindow is not an integer"); + name2message.put("frequency-badtimerange_start", "Invalid timeRange"); + name2message.put("frequency-badtimerange_end", "Invalid timeRange"); + name2message.put("frequency-badtimerange_value", "timestamp 99:99:99 could not be parsed"); name2message.put("minmax-notarget", "Missing target field in minmax policy"); name2message.put("minmax-nominmax", "Missing min or max field in minmax policy"); name2message.put("blacklist-noblacklist", "Missing blacklist"); @@ -223,7 +226,7 @@ public class GuardTranslatorTest { boolean foundOperation = false; boolean foundTarget = false; boolean foundControlLoop = false; - boolean foundTimeRange = false; + //boolean foundTimeRange = false; assertThat(xacmlPolicy.getTarget()).isNotNull(); assertThat(xacmlPolicy.getTarget().getAnyOf()).isNotEmpty(); @@ -257,11 +260,13 @@ public class GuardTranslatorTest { assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_CONTROLLOOP); foundControlLoop = true; } + /* if (XACML3.ID_ENVIRONMENT_CURRENT_TIME.toString().equals( match.getAttributeDesignator().getAttributeId())) { assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TIMERANGE); foundTimeRange = true; } + */ } } } @@ -274,7 +279,8 @@ public class GuardTranslatorTest { assertThat(foundControlLoop).isTrue(); } if (policy.getProperties().containsKey(GuardTranslator.FIELD_TIMERANGE)) { - assertThat(foundTimeRange).isTrue(); + assertThat(xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) + .hasAtLeastOneElementOfType(VariableDefinitionType.class); } } diff --git a/applications/guard/src/test/resources/requests/guard.timeinrange.json b/applications/guard/src/test/resources/requests/guard.timeinrange.json new file mode 100644 index 00000000..709796c2 --- /dev/null +++ b/applications/guard/src/test/resources/requests/guard.timeinrange.json @@ -0,0 +1,15 @@ +{ + "ONAPName": "Policy", + "ONAPComponent": "drools-pdp", + "ONAPInstance": "usecase-template", + "requestId": "unique-request-id-1", + "action": "guard", + "resource": { + "guard": { + "actor": "ACTOR", + "operation": "OPERATION", + "clname": "LOOP", + "target": "vnf1" + } + } +} diff --git a/applications/guard/src/test/resources/test-bad-policies.yaml b/applications/guard/src/test/resources/test-bad-policies.yaml index eb39aded..bdc8ba78 100644 --- a/applications/guard/src/test/resources/test-bad-policies.yaml +++ b/applications/guard/src/test/resources/test-bad-policies.yaml @@ -14,6 +14,48 @@ topology_template: properties: limit: 5 timeWindow: i am a bad value + - frequency-badtimerange_start: + type: onap.policies.controlloop.guard.common.FrequencyLimiter + type_version: 1.0.0 + version: 1.0.0 + properties: + actor: APPC + operation: Restart + timeRange: + startTime: 08:00:00Z + end_time: 23:59:59Z + id: loop-3 + timeWindow: 8 + timeUnits: hour + limit: 0 + - frequency-badtimerange_end: + type: onap.policies.controlloop.guard.common.FrequencyLimiter + type_version: 1.0.0 + version: 1.0.0 + properties: + actor: APPC + operation: Restart + timeRange: + start_time: 08:00:00Z + endTime: 23:59:59Z + id: loop-3 + timeWindow: 8 + timeUnits: hour + limit: 0 + - frequency-badtimerange_value: + type: onap.policies.controlloop.guard.common.FrequencyLimiter + type_version: 1.0.0 + version: 1.0.0 + properties: + actor: APPC + operation: Restart + timeRange: + start_time: 99:99:99 + end_time: 23:59:59Z + id: loop-3 + timeWindow: 8 + timeUnits: hour + limit: 0 - minmax-notarget: type: onap.policies.controlloop.guard.common.MinMax type_version: 1.0.0 diff --git a/applications/guard/src/test/resources/test-policies.yaml b/applications/guard/src/test/resources/test-policies.yaml index e33f116a..c92006e3 100644 --- a/applications/guard/src/test/resources/test-policies.yaml +++ b/applications/guard/src/test/resources/test-policies.yaml @@ -49,8 +49,8 @@ topology_template: actor: APPC operation: Restart timeRange: - start_time: T00:00:00Z - end_time: T08:00:00Z + start_time: 08:00:00Z + end_time: 23:59:59Z id: loop-3 timeWindow: 8 timeUnits: hour diff --git a/applications/guard/src/test/resources/test-time-in-range.yaml b/applications/guard/src/test/resources/test-time-in-range.yaml new file mode 100644 index 00000000..f9463fc1 --- /dev/null +++ b/applications/guard/src/test/resources/test-time-in-range.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - + guard.frequency.inrange: + type: onap.policies.controlloop.guard.common.FrequencyLimiter + type_version: 1.0.0 + version: 1.0.0 + name: guard.frequency.inrange + properties: + actor: ACTOR + operation: OPERATION + id: LOOP + timeWindow: 10 + timeUnits: minute + limit: 10 + timeRange: + start_time: 08:00:00+05:00 + end_time: 23:59:59+05:00 |