diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2020-03-08 10:41:26 -0400 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2020-03-09 14:12:45 -0400 |
commit | a0ad29cdb6d6f541aac59f9e265f79d3ad085560 (patch) | |
tree | e86ea9484f21d56bacf7c7c0d8fd6e85ab3121b3 /applications/guard/src/test/java/org | |
parent | e89d4c2ab8033c9482965f0e2f811e059378d37d (diff) |
Updates to support fixed guard policy types
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>
Diffstat (limited to 'applications/guard/src/test/java/org')
4 files changed, 550 insertions, 170 deletions
diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/CoordinationTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/CoordinationTest.java index c75156df..b5585a7c 100644 --- a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/CoordinationTest.java +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/CoordinationTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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; @@ -160,6 +163,16 @@ public class CoordinationTest { } /** + * 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(); - } - } } diff --git a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java index 9c3ae5b2..c62575c0 100644 --- a/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplicationTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 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(requestVfCount, PERMIT); // // 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(requestVfCount, DENY); } + @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 index 00000000..b3ef3bdd --- /dev/null +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardPolicyRequestTest.java @@ -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 index 00000000..36b43aee --- /dev/null +++ b/applications/guard/src/test/java/org/onap/policy/xacml/pdp/application/guard/GuardTranslatorTest.java @@ -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(); + } +} |