Updates to support fixed guard policy types 30/103330/3
authorPamela Dragosh <pdragosh@research.att.com>
Sun, 8 Mar 2020 14:41:26 +0000 (10:41 -0400)
committerPamela Dragosh <pdragosh@research.att.com>
Mon, 9 Mar 2020 18:12:45 +0000 (14:12 -0400)
Because the new TOSCA compliant policy types support required
fields, we can simplify the guard translator to utilize Match
in the target vs the previous complicated Condition usage.

Added test coverage to bump above 90% specifically for the
guard and coordination code.

Added a sonar exclusion for the test module.

Issue-ID: POLICY-2244
Change-Id: Ia90d117bd7b86d28a2268fd5ab8315dce7bf0c12
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
23 files changed:
applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaDictionary.java
applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/ToscaPolicyTranslatorUtils.java
applications/common/src/main/java/org/onap/policy/pdp/xacml/application/common/operationshistory/GetOperationOutcomePip.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/GuardPdpApplication.java
applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequest.java [moved from applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardPolicyRequest.java with 85% similarity]
applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslator.java [new file with mode: 0644]
applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/LegacyGuardTranslator.java [deleted file]
applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/CoordinationTest.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/GuardPolicyRequestTest.java [new file with mode: 0644]
applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java [new file with mode: 0644]
applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml [deleted file]
applications/guard/src/test/resources/requests/guard.vfCount.3.json [deleted file]
applications/guard/src/test/resources/requests/guard.vfCount.6.json [deleted file]
applications/guard/src/test/resources/requests/guard.vfCount.json [moved from applications/guard/src/test/resources/requests/guard.vfCount.1.json with 80% similarity]
applications/guard/src/test/resources/test-bad-policies.yaml [new file with mode: 0644]
applications/guard/src/test/resources/test-directive.yaml [new file with mode: 0644]
applications/guard/src/test/resources/test-policies.yaml [new file with mode: 0644]
applications/guard/src/test/resources/vDNS.policy.guard.blacklist.output.tosca.yaml [deleted file]
applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml [deleted file]
applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml [deleted file]
xacml-test/pom.xml

index c8dab3a..921babb 100644 (file)
@@ -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.
@@ -82,6 +82,10 @@ public final class ToscaDictionary {
             new IdentifierImpl(ID_URN_ONAP, "guard:target:min");
     public static final Identifier ID_RESOURCE_GUARD_MAX =
             new IdentifierImpl(ID_URN_ONAP, "guard:target:max");
+    public static final Identifier ID_RESOURCE_GUARD_TIMESTART =
+            new IdentifierImpl(ID_URN_ONAP, "guard.target:timestart");
+    public static final Identifier ID_RESOURCE_GUARD_TIMEEND =
+            new IdentifierImpl(ID_URN_ONAP, "guard.target:timeend");
 
     /*
      * This id specifically for guard is provided by the
index cdf5404..f1d3d5e 100644 (file)
@@ -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.
 package org.onap.policy.pdp.xacml.application.common;
 
 import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+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.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * This class contains static methods of helper classes to convert TOSCA policies
@@ -36,6 +40,7 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
  *
  */
 public final class ToscaPolicyTranslatorUtils {
+    private static final ObjectFactory factory = new ObjectFactory();
 
     private ToscaPolicyTranslatorUtils() {
         super();
@@ -99,4 +104,66 @@ public final class ToscaPolicyTranslatorUtils {
         }
         return allOf;
     }
+
+    /**
+     * Takes start and end time interval and generates an ApplyType for it.
+     *
+     * @param start ISO8601 timestamp
+     * @param end ISO8601 timestamp
+     * @return ApplyType
+     */
+    public static ApplyType generateTimeInRange(String start, String end) {
+        if (StringUtils.isBlank(start) || StringUtils.isBlank(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);
+
+
+        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;
+    }
+
+    /**
+     * Parses an integer value from the string.
+     *
+     * @param strInteger String representation of integer
+     * @return Integer object
+     */
+    public static Integer parseInteger(String strInteger) {
+        Integer theInt = null;
+        try {
+            theInt = Integer.parseInt(strInteger);
+        } catch (NumberFormatException e) {
+            try {
+                Double dblLimit = Double.parseDouble(strInteger);
+                theInt = dblLimit.intValue();
+            } catch (NumberFormatException e1) {
+                return null;
+            }
+        }
+        return theInt;
+    }
 }
index f2339b1..56d68d5 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * 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.
@@ -32,7 +32,7 @@ import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collection;
 import java.util.Properties;
-
+import javax.persistence.NoResultException;
 import javax.persistence.Persistence;
 
 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
@@ -101,14 +101,14 @@ public class GetOperationOutcomePip extends StdOnapPip {
         // Determine if the issuer is correct
         //
         if (Strings.isNullOrEmpty(pipRequest.getIssuer())) {
-            logger.debug("issuer is null - returning empty response");
+            logger.error("issuer is null - returning empty response");
             //
             // We only respond to ourself as the issuer
             //
             return StdPIPResponse.PIP_RESPONSE_EMPTY;
         }
         if (! pipRequest.getIssuer().startsWith(ToscaDictionary.GUARD_ISSUER_PREFIX)) {
-            logger.debug("Issuer does not start with guard");
+            logger.error("Issuer does not start with guard");
             //
             // We only respond to ourself as the issuer
             //
@@ -161,9 +161,11 @@ public class GetOperationOutcomePip extends StdOnapPip {
                 .setParameter(2, target)
                 .setMaxResults(1)
                 .getSingleResult();
+        } catch (NoResultException e) {
+            logger.trace("No results", e);
         } catch (Exception e) {
-            logger.error("Typed query failed ", e);
-            return null;
+            logger.error("Typed query failed", e);
         }
+        return null;
     }
 }
index 6fdb877..8b85a0d 100644 (file)
@@ -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.
@@ -22,6 +22,7 @@
 
 package org.onap.policy.pdp.xacml.application.common;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import java.lang.reflect.Constructor;
@@ -39,4 +40,9 @@ public class ToscaPolicyTranslatorUtilsTest {
 
     }
 
+    @Test
+    public void testTimeInRange() {
+        assertThat(ToscaPolicyTranslatorUtils.generateTimeInRange("T00:00:00Z", "T08:00:00Z")).isNotNull();
+    }
+
 }
index 0073f74..b4e431c 100644 (file)
@@ -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;
         }
     }
 
@@ -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 (file)
index 0000000..ebcae8d
--- /dev/null
@@ -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 (file)
index 0cb06ea..0000000
+++ /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;
-    }
-}
index c75156d..b5585a7 100644 (file)
@@ -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.
@@ -30,6 +30,7 @@ import java.io.IOException;
 import java.sql.Date;
 import java.time.Instant;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.ServiceLoader;
@@ -51,6 +52,8 @@ import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.resources.TextFileUtils;
 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.ToscaPolicyConversionException;
 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
@@ -159,6 +162,16 @@ public class CoordinationTest {
                 .createEntityManager();
     }
 
+    /**
+     * Close the entity manager.
+     */
+    @AfterClass
+    public static void cleanup() throws Exception {
+        if (em != null) {
+            em.close();
+        }
+    }
+
     /**
      * Clears the database before each test.
      *
@@ -170,52 +183,35 @@ public class CoordinationTest {
         em.getTransaction().commit();
     }
 
-    /**
-     * Check that decision matches expectation.
-     *
-     * @param expected from the response
-     * @param response received
-     *
-     **/
-    public void checkDecision(String expected, DecisionResponse response) throws CoderException {
-        LOGGER.info("Looking for {} Decision", expected);
-        assertThat(response).isNotNull();
-        assertThat(response.getStatus()).isNotNull();
-        assertThat(response.getStatus()).isEqualTo(expected);
-        //
-        // Dump it out as Json
-        //
-        LOGGER.info(gson.encode(response));
-    }
-
-    /**
-     * Request a decision and check that it matches expectation.
-     *
-     * @param request to send to Xacml PDP
-     * @param expected from the response
-     *
-     **/
-    public void requestAndCheckDecision(DecisionRequest request, String expected) throws CoderException {
-        //
-        // Ask for a decision
-        //
-        Pair<DecisionResponse, Response> decision = service.makeDecision(request, null);
-        //
-        // Check decision
-        //
-        checkDecision(expected, decision.getKey());
+    @Test
+    public void test0Basics() throws ToscaPolicyConversionException {
+        LOGGER.info("**************** Running test0Basics ****************");
+        //
+        // Check the methods in coordination translator that don't get tested by
+        // the application.
+        //
+        CoordinationGuardTranslator translator = new CoordinationGuardTranslator();
+        assertThat(translator.convertRequest(null)).isNull();
+        assertThat(translator.convertResponse(null)).isNull();
+        assertThat(CoordinationGuardTranslator.loadCoordinationDirectiveFromFile(
+                policyFolder.getRoot().getAbsolutePath() + "/nonexist.yaml")).isNull();
+        CoordinationDirective directive = CoordinationGuardTranslator.loadCoordinationDirectiveFromFile(
+                "src/test/resources/test-directive.yaml");
+        assertThat(directive).isNotNull();
     }
 
     @Test
-    public void test1() throws CoderException, IOException, XacmlApplicationException {
-        LOGGER.info("**************** Running test1 ****************");
+    public void test1Coordination() throws CoderException, IOException, XacmlApplicationException {
+        LOGGER.info("**************** Running test1Coordination ****************");
         //
         // Now load the test coordination policy - make sure
         // the pdp can support it and have it load
         // into the PDP.
         //
-        TestUtils.loadPolicies("src/test/resources/test.policy.guard.coordination.firstBlocksSecond.tosca.yaml",
-                service);
+        List<ToscaPolicy> loadedPolicies = TestUtils.loadPolicies(
+                "src/test/resources/test.policy.guard.coordination.firstBlocksSecond.tosca.yaml", service);
+        assertThat(loadedPolicies).isNotNull();
+        assertThat(loadedPolicies.get(0).getName()).isEqualTo("guard.coordination.firstBlocksSecond.test");
         //
         // cl1 doesn't have open action: cl2 should get permit
         //
@@ -266,6 +262,42 @@ public class CoordinationTest {
         requestAndCheckDecision(requestCl2Node1, DENY);
     }
 
+    /**
+     * Check that decision matches expectation.
+     *
+     * @param expected from the response
+     * @param response received
+     *
+     **/
+    public void checkDecision(String expected, DecisionResponse response) throws CoderException {
+        LOGGER.info("Looking for {} Decision", expected);
+        assertThat(response).isNotNull();
+        assertThat(response.getStatus()).isNotNull();
+        assertThat(response.getStatus()).isEqualTo(expected);
+        //
+        // Dump it out as Json
+        //
+        LOGGER.info(gson.encode(response));
+    }
+
+    /**
+     * Request a decision and check that it matches expectation.
+     *
+     * @param request to send to Xacml PDP
+     * @param expected from the response
+     *
+     **/
+    public void requestAndCheckDecision(DecisionRequest request, String expected) throws CoderException {
+        //
+        // Ask for a decision
+        //
+        Pair<DecisionResponse, Response> decision = service.makeDecision(request, null);
+        //
+        // Check decision
+        //
+        checkDecision(expected, decision.getKey());
+    }
+
     @SuppressWarnings("unchecked")
     private void insertOperationEvent(DecisionRequest request, String outcome) {
         //
@@ -288,14 +320,4 @@ public class CoordinationTest {
         em.persist(newEntry);
         em.getTransaction().commit();
     }
-
-    /**
-     * Close the entity manager.
-     */
-    @AfterClass
-    public static void cleanup() throws Exception {
-        if (em != null) {
-            em.close();
-        }
-    }
 }
index 9c3ae5b..c62575c 100644 (file)
@@ -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.
@@ -23,6 +23,7 @@
 package org.onap.policy.xacml.pdp.application.guard;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
 
 import com.att.research.xacml.api.Response;
 import java.io.File;
@@ -30,8 +31,8 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.sql.Date;
 import java.time.Instant;
-import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.ServiceLoader;
@@ -53,6 +54,7 @@ import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.resources.TextFileUtils;
 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.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
@@ -71,9 +73,7 @@ public class GuardPdpApplicationTest {
     private static File propertiesFile;
     private static RestServerParameters clientParams = new RestServerParameters();
     private static XacmlApplicationServiceProvider service;
-    private static DecisionRequest requestVfCount1;
-    private static DecisionRequest requestVfCount3;
-    private static DecisionRequest requestVfCount6;
+    private static DecisionRequest requestVfCount;
     private static StandardCoder gson = new StandardCoder();
     private static EntityManager em;
     private static final String DENY = "Deny";
@@ -132,17 +132,9 @@ public class GuardPdpApplicationTest {
         //
         // Load Decision Requests
         //
-        requestVfCount1 = gson.decode(
+        requestVfCount = gson.decode(
                 TextFileUtils.getTextFileAsString(
-                    "src/test/resources/requests/guard.vfCount.1.json"),
-                    DecisionRequest.class);
-        requestVfCount3 = gson.decode(
-                TextFileUtils.getTextFileAsString(
-                    "src/test/resources/requests/guard.vfCount.3.json"),
-                    DecisionRequest.class);
-        requestVfCount6 = gson.decode(
-                TextFileUtils.getTextFileAsString(
-                    "src/test/resources/requests/guard.vfCount.6.json"),
+                    "src/test/resources/requests/guard.vfCount.json"),
                     DecisionRequest.class);
         //
         // Create EntityManager for manipulating DB
@@ -154,7 +146,17 @@ public class GuardPdpApplicationTest {
     }
 
     /**
-     * Clears the database before each test.
+     * Close the entity manager.
+     */
+    @AfterClass
+    public static void cleanup() throws Exception {
+        if (em != null) {
+            em.close();
+        }
+    }
+
+    /**
+     * Clears the database before each test so there are no operations in it.
      *
      */
     @Before
@@ -202,7 +204,7 @@ public class GuardPdpApplicationTest {
 
     @Test
     public void test1Basics() throws CoderException, IOException {
-        LOGGER.info("**************** Running test1 ****************");
+        LOGGER.info("**************** Running test1Basics ****************");
         //
         // Make sure there's an application name
         //
@@ -219,17 +221,17 @@ public class GuardPdpApplicationTest {
         assertThat(service.supportedPolicyTypes()).isNotEmpty();
         assertThat(service.supportedPolicyTypes().size()).isEqualTo(4);
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0"))).isTrue();
+                "onap.policies.controlloop.guard.common.FrequencyLimiter", "1.0.0"))).isTrue();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1"))).isFalse();
+                "onap.policies.controlloop.guard.common.FrequencyLimiter", "1.0.1"))).isFalse();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.MinMax", "1.0.0"))).isTrue();
+                "onap.policies.controlloop.guard.common.MinMax", "1.0.0"))).isTrue();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.MinMax", "1.0.1"))).isFalse();
+                "onap.policies.controlloop.guard.common.MinMax", "1.0.1"))).isFalse();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.Blacklist", "1.0.0"))).isTrue();
+                "onap.policies.controlloop.guard.common.Blacklist", "1.0.0"))).isTrue();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
-                "onap.policies.controlloop.guard.Blacklist", "1.0.1"))).isFalse();
+                "onap.policies.controlloop.guard.common.Blacklist", "1.0.1"))).isFalse();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
                 "onap.policies.controlloop.guard.coordination.FirstBlocksSecond", "1.0.0"))).isTrue();
         assertThat(service.canSupportPolicyType(new ToscaPolicyTypeIdentifier(
@@ -239,146 +241,106 @@ public class GuardPdpApplicationTest {
 
     @Test
     public void test2NoPolicies() throws CoderException {
-        LOGGER.info("**************** Running test2 ****************");
-        requestAndCheckDecision(requestVfCount1,PERMIT);
+        LOGGER.info("**************** Running test2NoPolicies ****************");
+        assertThatCode(() -> requestAndCheckDecision(requestVfCount, PERMIT)).doesNotThrowAnyException();
     }
 
     @Test
     public void test3FrequencyLimiter() throws CoderException, FileNotFoundException, IOException,
         XacmlApplicationException {
-        LOGGER.info("**************** Running test3 ****************");
+        LOGGER.info("**************** Running test3FrequencyLimiter ****************");
         //
         // Now load the vDNS frequency limiter Policy - make sure
         // the pdp can support it and have it load
         // into the PDP.
         //
-        TestUtils.loadPolicies("src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml", service);
+        List<ToscaPolicy> loadedPolicies = TestUtils.loadPolicies(
+                "policies/vDNS.policy.guard.frequencylimiter.input.tosca.yaml", service);
+        assertThat(loadedPolicies).hasSize(1);
+        assertThat(loadedPolicies.get(0).getName()).isEqualTo("guard.frequency.scaleout");
         //
         // Zero recent actions: should get permit
         //
-        requestAndCheckDecision(requestVfCount1,PERMIT);
+        requestAndCheckDecision(requestVfCountPERMIT);
         //
         // Add entry into operations history DB
         //
-        insertOperationEvent(requestVfCount1);
-        //
-        // Only one recent actions: should get permit
-        //
-        requestAndCheckDecision(requestVfCount1,PERMIT);
-        //
-        // Add entry into operations history DB
-        //
-        insertOperationEvent(requestVfCount1);
+        insertOperationEvent(requestVfCount);
         //
         // Two recent actions, more than specified limit of 2: should get deny
         //
-        requestAndCheckDecision(requestVfCount1,DENY);
+        requestAndCheckDecision(requestVfCountDENY);
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void test4MinMax() throws CoderException, FileNotFoundException, IOException, XacmlApplicationException {
-        LOGGER.info("**************** Running test4 ****************");
+        LOGGER.info("**************** Running test4MinMax ****************");
         //
         // Now load the vDNS min max Policy - make sure
         // the pdp can support it and have it load
         // into the PDP.
         //
-        TestUtils.loadPolicies("src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml", service);
+        List<ToscaPolicy> loadedPolicies = TestUtils.loadPolicies(
+                "policies/vDNS.policy.guard.minmaxvnfs.input.tosca.yaml", service);
+        assertThat(loadedPolicies).hasSize(1);
+        assertThat(loadedPolicies.get(0).getName()).isEqualTo("guard.minmax.scaleout");
         //
-        // vfcount=1 below min of 2: should get a Deny
+        // vfcount=0 below min of 1: should get a Permit
         //
-        requestAndCheckDecision(requestVfCount1, DENY);
+        requestAndCheckDecision(requestVfCount, PERMIT);
         //
-        // vfcount=3 between min of 2 and max of 5: should get a Permit
+        // vfcount=1 between min of 1 and max of 2: should get a Permit
         //
-        requestAndCheckDecision(requestVfCount3, PERMIT);
+        ((Map<String, Object>) requestVfCount.getResource().get("guard")).put("vfCount", 1);
+        requestAndCheckDecision(requestVfCount, PERMIT);
         //
-        // vfcount=6 above max of 5: should get a Deny
+        // vfcount=2 hits the max of 2: should get a Deny
         //
-        requestAndCheckDecision(requestVfCount6,DENY);
+        ((Map<String, Object>) requestVfCount.getResource().get("guard")).put("vfCount", 2);
+        requestAndCheckDecision(requestVfCount, DENY);
         //
-        // Add two entry into operations history DB
+        // vfcount=3 above max of 2: should get a Deny
         //
-        insertOperationEvent(requestVfCount1);
-        insertOperationEvent(requestVfCount1);
+        ((Map<String, Object>) requestVfCount.getResource().get("guard")).put("vfCount", 3);
+        requestAndCheckDecision(requestVfCount,DENY);
         //
-        // vfcount=3 between min of 2 and max of 5, but 2 recent actions is above frequency limit: should get a Deny
+        // Insert entry into operations history DB - to indicate a successful
+        // VF Module Create.
         //
-        requestAndCheckDecision(requestVfCount3, DENY);
+        insertOperationEvent(requestVfCount);
         //
-        // vfcount=6 above max of 5: should get a Deny
+        // vfcount=1 between min of 1 and max of 2; MinMax should succeed,
+        // BUT the frequency limiter should fail
         //
-        requestAndCheckDecision(requestVfCount6, DENY);
-    }
-
-    @Test
-    public void test5MissingFields() throws FileNotFoundException, IOException, XacmlApplicationException,
-        CoderException {
-        LOGGER.info("**************** Running test5 ****************");
-        //
-        // Most likely we would not get a policy with missing fields passed to
-        // us from the API. But in case that happens, or we decide that some fields
-        // will be optional due to re-working of how the XACML policies are built,
-        // let's add support in for that.
-        //
-        TestUtils.loadPolicies("src/test/resources/guard.policy-minmax-missing-fields1.yaml", service);
-        //
-        // We can create a DecisionRequest on the fly - no need
-        // to have it in the .json files
-        //
-        DecisionRequest request = new DecisionRequest();
-        request.setOnapName("JUnit");
-        request.setOnapComponent("test5MissingFields");
-        request.setRequestId(UUID.randomUUID().toString());
-        request.setAction("guard");
-        Map<String, Object> guard = new HashMap<>();
-        guard.put("actor", "FOO");
-        guard.put("recipe", "bar");
-        guard.put("vfCount", "4");
-        Map<String, Object> resource = new HashMap<>();
-        resource.put("guard", guard);
-        request.setResource(resource);
-        //
-        // Ask for a decision - should get permit
-        //
-        Pair<DecisionResponse, Response> decision = service.makeDecision(request, null);
-        LOGGER.info("Looking for Permit Decision {}", decision.getKey());
-        assertThat(decision.getKey()).isNotNull();
-        assertThat(decision.getKey().getStatus()).isNotNull();
-        assertThat(decision.getKey().getStatus()).isEqualTo("Permit");
-        //
-        // Try a deny
-        //
-        guard.put("vfCount", "10");
-        resource.put("guard", guard);
-        request.setResource(resource);
-        decision = service.makeDecision(request, null);
-        LOGGER.info("Looking for Deny Decision {}", decision.getKey());
-        assertThat(decision.getKey()).isNotNull();
-        assertThat(decision.getKey().getStatus()).isNotNull();
-        assertThat(decision.getKey().getStatus()).isEqualTo("Deny");
+        ((Map<String, Object>) requestVfCount.getResource().get("guard")).put("vfCount", 1);
+        requestAndCheckDecision(requestVfCount, DENY);
     }
 
     @SuppressWarnings("unchecked")
     @Test
-    public void test6Blacklist() throws CoderException, XacmlApplicationException {
-        LOGGER.info("**************** Running test4 ****************");
+    public void test5Blacklist() throws CoderException, XacmlApplicationException {
+        LOGGER.info("**************** Running test5Blacklist ****************");
         //
-        // Setup requestVfCount1 to point to another target for this test
+        // Load the blacklist policy in with the others.
         //
-        ((Map<String, Object>)requestVfCount3.getResource().get("guard")).put("targets", "vLoadBalancer-01");
+        List<ToscaPolicy> loadedPolicies = TestUtils.loadPolicies(
+                "policies/vDNS.policy.guard.blacklist.input.tosca.yaml", service);
+        assertThat(loadedPolicies).hasSize(1);
+        assertThat(loadedPolicies.get(0).getName()).isEqualTo("guard.blacklist.scaleout");
         //
-        // vfcount=1 above min of 2: should get a permit
+        // vfcount=0 below min of 1: should get a Permit because target is NOT blacklisted
         //
-        requestAndCheckDecision(requestVfCount3, PERMIT);
+        requestAndCheckDecision(requestVfCount, PERMIT);
         //
-        // Now load the vDNS blacklist policy
+        // vfcount=1 between min of 1 and max of 2: change the
         //
-        TestUtils.loadPolicies("src/test/resources/vDNS.policy.guard.blacklist.output.tosca.yaml", service);
+        ((Map<String, Object>) requestVfCount.getResource().get("guard"))
+            .put("target", "the-vfmodule-where-root-is-true");
         //
-        // vfcount=1 above min of 2: should get a permit
+        // vfcount=0 below min of 1: should get a Deny because target IS blacklisted
         //
-        requestAndCheckDecision(requestVfCount3, DENY);
+        requestAndCheckDecision(requestVfCount, DENY);
     }
 
     @SuppressWarnings("unchecked")
@@ -406,14 +368,4 @@ public class GuardPdpApplicationTest {
         em.getTransaction().commit();
     }
 
-    /**
-     * Close the entity manager.
-     */
-    @AfterClass
-    public static void cleanup() throws Exception {
-        if (em != null) {
-            em.close();
-        }
-    }
-
 }
diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequestTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequestTest.java
new file mode 100644 (file)
index 0000000..b3ef3bd
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * ============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 static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.models.decisions.concepts.DecisionRequest;
+
+public class GuardPolicyRequestTest {
+
+    @Test
+    public void testAnomalies() {
+        DecisionRequest decisionRequest = new DecisionRequest();
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        Map<String, Object> resources = new HashMap<>();
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        resources.put("notguard", "foo");
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        resources.put("guard", null);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        Map<String, Object> guard = new HashMap<>();
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("crap", "notused");
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("actor", "notused");
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("recipe", "notused");
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("clname", "notused");
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("target", "notused");
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+
+        guard.put("vfCount", 1);
+        resources.put("guard", guard);
+        decisionRequest.setResource(resources);
+        assertThat(GuardPolicyRequest.createInstance(decisionRequest)).isNotNull();
+    }
+
+}
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
new file mode 100644 (file)
index 0000000..36b43ae
--- /dev/null
@@ -0,0 +1,319 @@
+/*-
+ * ============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 static org.assertj.core.api.Assertions.assertThat;
+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;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.XACMLPolicyWriter;
+import java.io.ByteArrayOutputStream;
+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.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 org.junit.Test;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+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.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
+import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
+import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GuardTranslatorTest {
+    private static final Logger LOGGER = LoggerFactory.getLogger(GuardTranslatorTest.class);
+    private static final StandardYamlCoder yamlCoder = new StandardYamlCoder();
+    private static StandardCoder gson = new StandardCoder();
+
+    private GuardTranslator translator = new GuardTranslator();
+
+    @Test
+    public void testRequest() throws Exception {
+        DecisionRequest decisionRequest = gson.decode(
+                TextFileUtils.getTextFileAsString(
+                        "src/test/resources/requests/guard.vfCount.json"),
+                        DecisionRequest.class);
+        Request xacmlRequest = translator.convertRequest(decisionRequest);
+
+        assertThat(xacmlRequest).isNotNull();
+    }
+
+    @Test
+    public void testResponse() {
+        StdStatus status = new StdStatus(StdStatusCode.STATUS_CODE_OK);
+        StdMutableResult result = new StdMutableResult(Decision.PERMIT, status);
+        StdMutableResponse response = new StdMutableResponse(result);
+
+        DecisionResponse decisionResponse = translator.convertResponse(response);
+        assertThat(decisionResponse).isNotNull();
+        assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
+
+        result = new StdMutableResult(Decision.DENY, status);
+        response = new StdMutableResponse(result);
+        decisionResponse = translator.convertResponse(response);
+        assertThat(decisionResponse).isNotNull();
+        assertThat(decisionResponse.getStatus()).isEqualTo(Decision.DENY.toString());
+
+        result = new StdMutableResult(Decision.INDETERMINATE, status);
+        response = new StdMutableResponse(result);
+        decisionResponse = translator.convertResponse(response);
+        assertThat(decisionResponse).isNotNull();
+        assertThat(decisionResponse.getStatus()).isEqualTo(Decision.PERMIT.toString());
+    }
+
+
+    @Test
+    public void testBadPolicies() throws Exception {
+        String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-bad-policies.yaml");
+        //
+        // Serialize it into a class
+        //
+        ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
+        //
+        // Make sure all the fields are setup properly
+        //
+        JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
+        jtst.fromAuthorative(serviceTemplate);
+        ToscaServiceTemplate completedJtst = jtst.toAuthorative();
+        //
+        // Get the policies
+        //
+        for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
+            for (ToscaPolicy policy : policies.values()) {
+                if ("frequency-missing-properties".equals(policy.getName())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy)
+                    ).withMessageContaining("Missing property limit");
+                } else if ("frequency-timewindow".equals(policy.getName())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy)
+                    ).withMessageContaining("timeWindow is not an integer");
+                } else if ("minmax-notarget".equals(policy.getName())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy)
+                    ).withMessageContaining("Missing target field in minmax policy");
+                } else if ("minmax-nominmax".equals(policy.getName())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy)
+                    ).withMessageContaining("Missing min or max field in minmax policy");
+                } else if ("blacklist-noblacklist".equals(policy.getName())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy)
+                    ).withMessageContaining("Missing blacklist");
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testPolicyConversion() throws Exception {
+        String policyYaml = ResourceUtils.getResourceAsString("src/test/resources/test-policies.yaml");
+        //
+        // Serialize it into a class
+        //
+        ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyYaml, ToscaServiceTemplate.class);
+        //
+        // Make sure all the fields are setup properly
+        //
+        JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
+        jtst.fromAuthorative(serviceTemplate);
+        ToscaServiceTemplate completedJtst = jtst.toAuthorative();
+        //
+        // Get the policies
+        //
+        for (Map<String, ToscaPolicy> policies : completedJtst.getToscaTopologyTemplate().getPolicies()) {
+            for (ToscaPolicy policy : policies.values()) {
+                //
+                // Convert the policy
+                //
+                if ("onap.policies.controlloop.guard.common.Unknown".equals(policy.getType())) {
+                    assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
+                        translator.convertPolicy(policy));
+                    continue;
+                }
+                PolicyType xacmlPolicy = translator.convertPolicy(policy);
+                assertThat(xacmlPolicy).isNotNull();
+                //
+                // Let's dump it out
+                //
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                XACMLPolicyWriter.writePolicyFile(os, xacmlPolicy);
+                LOGGER.info(os.toString());
+                //
+                // Validate the policy
+                //
+                assertThat(xacmlPolicy.getPolicyId()).isEqualTo(policy.getName());
+                assertThat(xacmlPolicy.getVersion()).isEqualTo(policy.getVersion());
+                assertThat(xacmlPolicy.getRuleCombiningAlgId()).isNotNull();
+                validateCommon(policy, xacmlPolicy);
+                //
+                // Validate each policy type
+                //
+                if (GuardTranslator.POLICYTYPE_FREQUENCY.equals(policy.getType())) {
+                    validateFrequency(policy, xacmlPolicy);
+                } else if (GuardTranslator.POLICYTYPE_MINMAX.equals(policy.getType())) {
+                    validateMinMax(policy, xacmlPolicy);
+                } else if (GuardTranslator.POLICYTYPE_BLACKLIST.equals(policy.getType())) {
+                    validateBlacklist(policy, xacmlPolicy);
+                }
+            }
+        }
+    }
+
+    private void validateCommon(ToscaPolicy policy, PolicyType xacmlPolicy) {
+        boolean foundActor = false;
+        boolean foundOperation = false;
+        boolean foundTarget = false;
+        boolean foundControlLoop = false;
+        boolean foundTimeRange = false;
+
+        assertThat(xacmlPolicy.getTarget()).isNotNull();
+        assertThat(xacmlPolicy.getTarget().getAnyOf()).isNotEmpty();
+        for (AnyOfType anyOf : xacmlPolicy.getTarget().getAnyOf()) {
+            assertThat(anyOf.getAllOf()).isNotEmpty();
+            for (AllOfType allOf : anyOf.getAllOf()) {
+                assertThat(allOf.getMatch()).isNotEmpty();
+                for (MatchType match : allOf.getMatch()) {
+                    //
+                    // These fields are required
+                    //
+                    if (ToscaDictionary.ID_RESOURCE_GUARD_ACTOR.toString().equals(
+                            match.getAttributeDesignator().getAttributeId())) {
+                        assertThat(match.getAttributeValue().getContent()).isNotNull();
+                        foundActor = true;
+                    } else if (ToscaDictionary.ID_RESOURCE_GUARD_RECIPE.toString().equals(
+                            match.getAttributeDesignator().getAttributeId())) {
+                        assertThat(match.getAttributeValue().getContent()).isNotNull();
+                        foundOperation = true;
+                    } else {
+                        //
+                        // These fields are optional
+                        //
+                        if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
+                                match.getAttributeDesignator().getAttributeId())) {
+                            assertThat(policy.getProperties()).containsKey("target");
+                            foundTarget = true;
+                        }
+                        if (ToscaDictionary.ID_RESOURCE_GUARD_CLNAME.toString().equals(
+                                match.getAttributeDesignator().getAttributeId())) {
+                            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;
+                        }
+                    }
+                }
+            }
+        }
+        assertThat(foundActor && foundOperation).isTrue();
+        if (policy.getProperties().containsKey("target")) {
+            assertThat(foundTarget).isTrue();
+        }
+        if (policy.getProperties().containsKey(GuardTranslator.FIELD_CONTROLLOOP)) {
+            assertThat(foundControlLoop).isTrue();
+        }
+        if (policy.getProperties().containsKey(GuardTranslator.FIELD_TIMERANGE)) {
+            assertThat(foundTimeRange).isTrue();
+        }
+    }
+
+    private void validateFrequency(ToscaPolicy policy, PolicyType xacmlPolicy) {
+        for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
+            if (! (rule instanceof RuleType)) {
+                continue;
+            }
+            assertThat(((RuleType)rule).getCondition()).isNotNull();
+            assertThat(((RuleType)rule).getCondition().getExpression()).isNotNull();
+        }
+    }
+
+    private void validateMinMax(ToscaPolicy policy, PolicyType xacmlPolicy) {
+        boolean foundTarget = false;
+        boolean foundMinOrMax = false;
+        for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
+            if (! (rule instanceof RuleType)) {
+                continue;
+            }
+            for (AnyOfType anyOf : ((RuleType)rule).getTarget().getAnyOf()) {
+                assertThat(anyOf.getAllOf()).isNotEmpty();
+                for (AllOfType allOf : anyOf.getAllOf()) {
+                    assertThat(allOf.getMatch()).isNotEmpty();
+                    for (MatchType match : allOf.getMatch()) {
+                        if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
+                                match.getAttributeDesignator().getAttributeId())) {
+                            assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_TARGET);
+                            foundTarget = true;
+                        } else if (ToscaDictionary.ID_RESOURCE_GUARD_VFCOUNT.toString().equals(
+                                match.getAttributeDesignator().getAttributeId())) {
+                            assertThat(policy.getProperties().keySet()).containsAnyOf(GuardTranslator.FIELD_MIN,
+                                    GuardTranslator.FIELD_MAX);
+                            foundMinOrMax = true;
+                        }
+                    }
+                }
+            }
+        }
+        assertThat(foundTarget && foundMinOrMax).isTrue();
+    }
+
+    private void validateBlacklist(ToscaPolicy policy, PolicyType xacmlPolicy) {
+        boolean foundBlacklist = false;
+        for (Object rule : xacmlPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
+            if (! (rule instanceof RuleType)) {
+                continue;
+            }
+            for (AnyOfType anyOf : ((RuleType)rule).getTarget().getAnyOf()) {
+                assertThat(anyOf.getAllOf()).isNotEmpty();
+                for (AllOfType allOf : anyOf.getAllOf()) {
+                    assertThat(allOf.getMatch()).isNotEmpty();
+                    for (MatchType match : allOf.getMatch()) {
+                        if (ToscaDictionary.ID_RESOURCE_GUARD_TARGETID.toString().equals(
+                                match.getAttributeDesignator().getAttributeId())) {
+                            assertThat(policy.getProperties()).containsKey(GuardTranslator.FIELD_BLACKLIST);
+                            foundBlacklist = true;
+                        }
+                    }
+                }
+            }
+        }
+        assertThat(foundBlacklist).isTrue();
+    }
+}
diff --git a/applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml b/applications/guard/src/test/resources/guard.policy-minmax-missing-fields1.yaml
deleted file mode 100644 (file)
index 6a44118..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0_0
-topology_template:
-  policies:
-    -
-      guard.minmax.missing1:
-        type: onap.policies.controlloop.guard.MinMax
-        version: 1.0.0
-        metadata:
-          policy-id : guard.minmax.scaleout
-          policy-version: 1
-        properties:
-          actor: FOO
-          recipe: bar
-#          targets: *.
-#          clname: ControlLoop-Foo-Bar
-          min: 1
-          max: 5
-#          guardActiveStart: 00:00:01-05:00
-#          guardActiveEnd: 23:59:59-05:00
diff --git a/applications/guard/src/test/resources/requests/guard.vfCount.3.json b/applications/guard/src/test/resources/requests/guard.vfCount.3.json
deleted file mode 100644 (file)
index 9faa55d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "ONAPName": "Policy",
-  "ONAPComponent": "drools-pdp",
-  "ONAPInstance": "usecase-template",
-  "requestId": "unique-request-id-3",
-  "action": "guard",
-  "resource": {
-      "guard": {
-          "actor": "SO",
-          "recipe": "VF Module Create",
-          "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
-          "target": "vLoadBalancer-00",
-          "vfCount": "3"
-      }
-  }
-}
diff --git a/applications/guard/src/test/resources/requests/guard.vfCount.6.json b/applications/guard/src/test/resources/requests/guard.vfCount.6.json
deleted file mode 100644 (file)
index e00d67a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "ONAPName": "Policy",
-  "ONAPComponent": "drools-pdp",
-  "ONAPInstance": "usecase-template",
-  "requestId": "unique-request-id-2",
-  "action": "guard",
-  "resource": {
-      "guard": {
-          "actor": "SO",
-          "recipe": "VF Module Create",
-          "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
-          "target": "vLoadBalancer-00",
-          "vfCount" : "6"
-      }
-  }
-}
@@ -9,8 +9,8 @@
           "actor": "SO",
           "recipe": "VF Module Create",
           "clname": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
-          "target": "vLoadBalancer-00",
-          "vfCount": "1"
+          "target": "e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e",
+          "vfCount": "0"
       }
   }
 }
diff --git a/applications/guard/src/test/resources/test-bad-policies.yaml b/applications/guard/src/test/resources/test-bad-policies.yaml
new file mode 100644 (file)
index 0000000..df2431d
--- /dev/null
@@ -0,0 +1,35 @@
+tosca_definitions_version: tosca_simple_yaml_1_1_0
+topology_template:
+  policies:
+    -
+      frequency-missing-properties:
+        type: onap.policies.controlloop.guard.common.FrequencyLimiter
+        type_version: 1.0.0
+        version: 1.0.0
+    -
+      frequency-timewindow:
+        type: onap.policies.controlloop.guard.common.FrequencyLimiter
+        type_version: 1.0.0
+        version: 1.0.0
+        properties:
+            limit: 5
+            timeWindow: i am a bad value
+    -
+      minmax-notarget:
+        type: onap.policies.controlloop.guard.common.MinMax
+        type_version: 1.0.0
+        version: 1.0.0
+        properties:
+    -
+      minmax-nominmax:
+        type: onap.policies.controlloop.guard.common.MinMax
+        type_version: 1.0.0
+        version: 1.0.0
+        properties:
+            target: foo
+    -
+      blacklist-noblacklist:
+        type: onap.policies.controlloop.guard.common.Blacklist
+        type_version: 1.0.0
+        version: 1.0.0
+        properties:
diff --git a/applications/guard/src/test/resources/test-directive.yaml b/applications/guard/src/test/resources/test-directive.yaml
new file mode 100644 (file)
index 0000000..44dfa74
--- /dev/null
@@ -0,0 +1,4 @@
+controlLoop:
+    - cl1
+    - cl2
+directive: whatisthisvaluesupposedtobe
diff --git a/applications/guard/src/test/resources/test-policies.yaml b/applications/guard/src/test/resources/test-policies.yaml
new file mode 100644 (file)
index 0000000..1ac7271
--- /dev/null
@@ -0,0 +1,116 @@
+tosca_definitions_version: tosca_simple_yaml_1_1_0
+topology_template:
+  policies:
+    -
+      frequency-default:
+        type: onap.policies.controlloop.guard.common.FrequencyLimiter
+        type_version: 1.0.0
+        version: 1.0.0
+        description: |
+            This is the default APPC Restart frequency limiter policy for all control loops.
+        metadata:
+          policy-id: frequency-default
+          policy-version: 1.0.0
+        properties:
+          actor: APPC
+          operation: Restart
+          timeWindow: 10
+          timeUnits: minute
+          limit: 1
+    -
+      frequency-loop-1:
+        type: onap.policies.controlloop.guard.common.FrequencyLimiter
+        type_version: 1.0.0
+        version: 1.0.0
+        description: |
+            This frequency limiter is for APPC Restart on a specific control loop. It allows more restarts.
+        metadata:
+          policy-id: frequency-loop-1
+          policy-version: 1.0.0
+        properties:
+          actor: APPC
+          operation: Restart
+          id: loop-1
+          timeWindow: 10
+          timeUnits: minute
+          limit: 3
+    -
+      frequency-loop-3:
+        type: onap.policies.controlloop.guard.common.FrequencyLimiter
+        type_version: 1.0.0
+        version: 1.0.0
+        description: |
+            This frequency limiter is for APPC Restart on a specific control loop. It allows
+            NO restarts in a time frame.
+        metadata:
+          policy-id: frequency-loop-3
+          policy-version: 1.0.0
+        properties:
+          actor: APPC
+          operation: Restart
+          timeRange:
+            start_time: T00:00:00Z
+            end_time: T08:00:00Z
+          id: loop-3
+          timeWindow: 8
+          timeUnits: hour
+          limit: 0
+    -
+      minmax-default:
+        type: onap.policies.controlloop.guard.common.MinMax
+        type_version: 1.0.0
+        version: 1.0.0
+        metadata:
+          policy-id : minmax-default
+          policy-version: 1.0.0
+        properties:
+          actor: SO
+          operation: VF Module Create
+          target: vf-module-id-1
+          min: 1
+          max: 5
+    -
+      minmax-vfmodule-loop2:
+        type: onap.policies.controlloop.guard.common.MinMax
+        type_version: 1.0.0
+        version: 1.0.0
+        metadata:
+          policy-id : minmax-vfmodule-loop2
+          policy-version: 1.0.0
+        properties:
+          actor: SO
+          operation: VF Module Create
+          id: loop-2
+          target: vf-module-id-2
+          min: 3
+          max: 6
+    -
+      blacklist-1:
+        type: onap.policies.controlloop.guard.common.Blacklist
+        type_version: 1.0.0
+        version: 1.0.0
+        metadata:
+          policy-id : blacklist-1
+          policy-version: 1.0.0
+        properties:
+          actor: APPC
+          operation: Migrate
+          id: loop-5
+          blacklist:
+              - vnf1
+              - vnf2
+    -
+      unknown-1:
+        type: onap.policies.controlloop.guard.common.Unknown
+        type_version: 1.0.0
+        version: 1.0.0
+        metadata:
+          policy-id : unknown-1
+          policy-version: 1.0.0
+        properties:
+          actor: APPC
+          operation: Migrate
+          id: loop-5
+          blacklist:
+              - vnf1
+              - vnf2
\ No newline at end of file
diff --git a/applications/guard/src/test/resources/vDNS.policy.guard.blacklist.output.tosca.yaml b/applications/guard/src/test/resources/vDNS.policy.guard.blacklist.output.tosca.yaml
deleted file mode 100644 (file)
index 7d3a54e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0_0
-topology_template:
-  policies:
-    -
-      guard.frequency.scaleout:
-        type: onap.policies.controlloop.guard.Blacklist
-        version: 1.0.0
-        metadata:
-          policy-id: guard.frequency.scaleout
-          policy-version: 1
-        properties:
-          actor: SO
-          recipe: VF Module Create
-          targets: vLoadBalancer-01
-          clname: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
-          limit: 2
-          guardActiveStart: 00:00:00Z
-          guardActiveEnd: 23:59:59Z
diff --git a/applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml b/applications/guard/src/test/resources/vDNS.policy.guard.frequency.output.tosca.yaml
deleted file mode 100644 (file)
index 506a44e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0_0
-topology_template:
-  policies:
-    -
-      guard.frequency.scaleout:
-        type: onap.policies.controlloop.guard.FrequencyLimiter
-        version: 1.0.0
-        metadata:
-          policy-id: guard.frequency.scaleout
-          policy-version: 1
-        properties:
-          actor: SO
-          recipe: VF Module Create
-          targets: .*
-          clname: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
-          limit: 2
-          timeWindow: 10
-          timeUnits: minute
-          guardActiveStart: 00:00:00Z
-          guardActiveEnd: 23:59:59Z
diff --git a/applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml b/applications/guard/src/test/resources/vDNS.policy.guard.minmax.output.tosca.yaml
deleted file mode 100644 (file)
index ff2a423..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0_0
-topology_template:
-  policies:
-    -
-      guard.minmax.scaleout:
-        type: onap.policies.controlloop.guard.MinMax
-        version: 1.0.0
-        metadata:
-          policy-id : guard.minmax.scaleout
-          policy-version: 1
-        properties:
-          actor: SO
-          recipe: VF Module Create
-          targets: .*
-          clname: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
-          min: 2
-          max: 5
-          guardActiveStart: 00:00:00Z
-          guardActiveEnd: 23:59:59Z
index 9127f56..12bd639 100644 (file)
 
     <artifactId>xacml-test</artifactId>
 
+    <properties>
+        <!-- There is code to support JUnit testing in this sub-module. -->
+        <sonar.skip>true</sonar.skip>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.onap.policy.xacml-pdp.applications</groupId>