Utilize time extensions 02/118002/5
authorPamela Dragosh <pdragosh@research.att.com>
Wed, 17 Feb 2021 21:48:01 +0000 (15:48 -0600)
committerPamela Dragosh <pdragosh@research.att.com>
Thu, 18 Feb 2021 16:28:38 +0000 (10:28 -0600)
Switched to using the new Time Extensions released in XACML
from github v3.0. Added more thorough tests for it as well as
the flexibility of specifying the current time etc.

More syntax checking on the inputs from the policy.

Issue-ID: POLICY-2810
Change-Id: I1b4ec885c706e37949e5dabe14c63b0d7456cd4f
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslatorUtils.java
applications/common/src/test/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslatorUtilsTest.java
applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java
applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java
applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java
applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java
applications/guard/src/test/resources/requests/guard.timeinrange.json [new file with mode: 0644]
applications/guard/src/test/resources/test-bad-policies.yaml
applications/guard/src/test/resources/test-policies.yaml
applications/guard/src/test/resources/test-time-in-range.yaml [new file with mode: 0644]

index 796499d..a5e804e 100644 (file)
@@ -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.
@@ -29,9 +29,11 @@ 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.MatchType;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
 import org.apache.commons.lang3.StringUtils;
 
 /**
@@ -114,7 +116,7 @@ public final class ToscaPolicyTranslatorUtils {
      * @param end ISO8601 timestamp
      * @return ApplyType
      */
-    public static ApplyType generateTimeInRange(String start, String end) {
+    public static ApplyType generateTimeInRange(String start, String end, boolean useRecurringFunction) {
         if (StringUtils.isBlank(start) || StringUtils.isBlank(end)) {
             return null;
         }
@@ -140,7 +142,11 @@ public final class ToscaPolicyTranslatorUtils {
 
         ApplyType applyTimeInRange = new ApplyType();
         applyTimeInRange.setDescription("return true if current time is in range.");
-        applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RANGE.stringValue());
+        if (useRecurringFunction) {
+            applyTimeInRange.setFunctionId(XACML3.ID_FUNCTION_TIME_IN_RECURRING_RANGE.stringValue());
+        } else {
+            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));
@@ -214,4 +220,24 @@ public final class ToscaPolicyTranslatorUtils {
         }
         return target;
     }
+
+    /**
+     * For an existing ConditionType, this method adds in a check for a variable. You must specify
+     * the function that compares the existing ConditionType's expression against the Variable.
+     *
+     * @param condition Existing ConditionType to use
+     * @param variable VariableReferenceType to use
+     * @param functionId XACML 3.0 identifier for the function
+     * @return a new ConditionType
+     */
+    public static ConditionType addVariableToCondition(ConditionType condition, VariableReferenceType variable,
+            Identifier functionId) {
+        ApplyType applyFunction = new ApplyType();
+        applyFunction.setFunctionId(functionId.stringValue());
+        applyFunction.getExpression().add(condition.getExpression());
+        applyFunction.getExpression().add(factory.createVariableReference(variable));
+        ConditionType newCondition = new ConditionType();
+        newCondition.setExpression(factory.createApply(applyFunction));
+        return newCondition;
+    }
 }
index 5d451e2..99627f6 100644 (file)
@@ -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.
@@ -25,15 +25,23 @@ package org.onap.policy.pdp.xacml.application.common;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import com.att.research.xacml.api.XACML3;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
 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.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
 import org.junit.Test;
 
 public class ToscaPolicyTranslatorUtilsTest {
+    private static final ObjectFactory factory = new ObjectFactory();
 
     @Test
     public void test() throws NoSuchMethodException, SecurityException {
@@ -45,7 +53,9 @@ public class ToscaPolicyTranslatorUtilsTest {
 
     @Test
     public void testTimeInRange() {
-        assertThat(ToscaPolicyTranslatorUtils.generateTimeInRange("T00:00:00Z", "T08:00:00Z")).isNotNull();
+        ApplyType apply = ToscaPolicyTranslatorUtils.generateTimeInRange("00:00:00Z", "08:00:00Z", true);
+        assertThat(apply).isNotNull();
+        assertThat(apply.getExpression()).hasSize(3);
     }
 
     @Test
@@ -68,4 +78,36 @@ public class ToscaPolicyTranslatorUtilsTest {
         assertThat(ToscaPolicyTranslatorUtils.parseInteger("1")).isEqualTo(1);
         assertThat(ToscaPolicyTranslatorUtils.parseInteger("1.0")).isEqualTo(1);
     }
+
+    @Test
+    public void testAddingVariables() {
+        ApplyType applyType = new ApplyType();
+        applyType.setFunctionId(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue());
+
+        AttributeValueType value = new AttributeValueType();
+        value.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
+        value.getContent().add("1");
+        applyType.getExpression().add(factory.createAttributeValue(value));
+
+        AttributeDesignatorType designator = new AttributeDesignatorType();
+        designator.setAttributeId(XACML3.ID_RESOURCE.stringValue());
+        designator.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue());
+        designator.setDataType(XACML3.ID_DATATYPE_STRING.stringValue());
+        applyType.getExpression().add(factory.createAttributeDesignator(designator));
+
+        ConditionType condition = new ConditionType();
+        condition.setExpression(factory.createApply(applyType));
+
+        VariableReferenceType variable = new VariableReferenceType();
+
+        variable.setVariableId("my-variable-id");
+
+        ConditionType newCondition = ToscaPolicyTranslatorUtils.addVariableToCondition(condition, variable,
+                XACML3.ID_FUNCTION_AND);
+
+        assertThat(newCondition.getExpression().getValue()).isInstanceOf(ApplyType.class);
+        Object obj = newCondition.getExpression().getValue();
+        assertThat(((ApplyType) obj).getFunctionId()).isEqualTo(XACML3.ID_FUNCTION_AND.stringValue());
+        assertThat(((ApplyType) obj).getExpression()).hasSize(2);
+    }
 }
index 8763596..7394ab3 100644 (file)
@@ -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.
 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
         //
index ddb9bb0..fd9bb00 100644 (file)
@@ -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,9 +168,55 @@ 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.
      */
@@ -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 {
         //
index 3b1b1c6..5b32b2a 100644 (file)
@@ -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) {
         //
index e4c958b..cf8c015 100644 (file)
@@ -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 (file)
index 0000000..709796c
--- /dev/null
@@ -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"
+      }
+  }
+}
index eb39ade..bdc8ba7 100644 (file)
@@ -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
index e33f116..c92006e 100644 (file)
@@ -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 (file)
index 0000000..f9463fc
--- /dev/null
@@ -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