From 70770572844f95a11206ae008dd62e42aedfe04d Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Mon, 26 Jul 2021 11:11:09 -0400 Subject: Add "configure" operation to xacml Added "configure" operation to xacml simulator and actor.xacml. Issue-ID: POLICY-3502 Change-Id: Ia206303c65ce4e54187d818da9253dabfe864d62 Signed-off-by: Jim Hahn --- models-interactions/model-simulators/pom.xml | 7 +- .../policy/simulators/XacmlSimulatorJaxRs.java | 78 +++++++++++++++--- .../onap/policy/simulators/XacmlSimulatorTest.java | 92 ++++++++++++++++++---- .../xacml/xacml.configure.invalid-policy.json | 4 + .../xacml/xacml.configure.test-policy.json | 22 ++++++ 5 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.invalid-policy.json create mode 100644 models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.test-policy.json (limited to 'models-interactions/model-simulators') diff --git a/models-interactions/model-simulators/pom.xml b/models-interactions/model-simulators/pom.xml index 8f7d35aaf..f778b07d4 100644 --- a/models-interactions/model-simulators/pom.xml +++ b/models-interactions/model-simulators/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= ONAP ================================================================================ - Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. Modifications Copyright (C) 2019 Nordix Foundation. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -90,6 +90,11 @@ gson provided + + org.onap.policy.models + policy-models-tosca + ${project.version} + org.onap.policy.models policy-models-decisions diff --git a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/XacmlSimulatorJaxRs.java b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/XacmlSimulatorJaxRs.java index f25b65c04..54023f6e5 100644 --- a/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/XacmlSimulatorJaxRs.java +++ b/models-interactions/model-simulators/src/main/java/org/onap/policy/simulators/XacmlSimulatorJaxRs.java @@ -22,21 +22,41 @@ package org.onap.policy.simulators; import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.decisions.concepts.DecisionRequest; import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Path("/policy/pdpx/v1") public class XacmlSimulatorJaxRs { + private static final Logger logger = LoggerFactory.getLogger(XacmlSimulatorJaxRs.class); + + public static final String POLICY_CONFIG_OPER_PREFIX = "org/onap/policy/simulators/xacml/xacml.configure."; public static final String DENY_CLNAME = "denyGuard"; + public static final Coder coder = new StandardCoder(); + + // @formatter:off + private Map> action2method = Map.of( + "guard", this::guardDecision, + "configure", this::configureDecision + ); + // @formatter:on /** - * Get a guard decision. + * Get a XACML decision. * * @param req the request * @return the response @@ -45,23 +65,55 @@ public class XacmlSimulatorJaxRs { @Path("/decision") @Consumes(MediaType.APPLICATION_JSON) @Produces("application/json") - public DecisionResponse getGuardDecision(DecisionRequest req) { + public DecisionResponse getDecision(DecisionRequest req) { + Function func = action2method.get(req.getAction()); + if (func != null) { + return func.apply(req); + } + + DecisionResponse response = new DecisionResponse(); + response.setMessage("unsupported action: " + req.getAction()); + return response; + } + + private DecisionResponse guardDecision(DecisionRequest req) { @SuppressWarnings("unchecked") Map guard = (Map) req.getResource().get("guard"); String clName = guard.get("clname"); + var response = new DecisionResponse(); - if (DENY_CLNAME.equals(clName)) { - response.setStatus("Deny"); - response.setAdvice(Collections.emptyMap()); - response.setObligations(Collections.emptyMap()); - response.setPolicies(Collections.emptyMap()); - return response; + response.setStatus(DENY_CLNAME.equals(clName) ? "Deny" : "Permit"); + response.setAdvice(Collections.emptyMap()); + response.setObligations(Collections.emptyMap()); + response.setPolicies(Collections.emptyMap()); + return response; + } + + private DecisionResponse configureDecision(DecisionRequest req) { + var response = new DecisionResponse(); + response.setPolicies(new HashMap<>()); + + Map resources = req.getResource(); + var policyId = resources.get("policy-id"); + if (policyId != null) { + String fileName = POLICY_CONFIG_OPER_PREFIX + policyId + ".json"; + try { + var policyJson = ResourceUtils.getResourceAsString(fileName); + var toscaServiceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class); + toscaServiceTemplate.getToscaTopologyTemplate().getPolicies() + .forEach(policyMap -> response.getPolicies().putAll(policyMap)); + } catch (CoderException e) { + logger.warn("cannot decode policy file: {}", fileName, e); + response.setMessage("cannot decode policy"); + } catch (NullPointerException e) { + logger.warn("cannot read policy simulator file", e); + response.setMessage("cannot read policy simulator file"); + } } else { - response.setStatus("Permit"); - response.setAdvice(Collections.emptyMap()); - response.setObligations(Collections.emptyMap()); - response.setPolicies(Collections.emptyMap()); - return response; + // the current simulator only supports searching by policy-id + // future changes may support getting policies by policy-type + response.setMessage("resource must contain policy-id key"); } + return response; } } diff --git a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/XacmlSimulatorTest.java b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/XacmlSimulatorTest.java index 53b476fb2..e188edc77 100644 --- a/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/XacmlSimulatorTest.java +++ b/models-interactions/model-simulators/src/test/java/org/onap/policy/simulators/XacmlSimulatorTest.java @@ -21,6 +21,7 @@ package org.onap.policy.simulators; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; @@ -60,35 +61,98 @@ public class XacmlSimulatorTest { @Test public void testGuard() throws CoderException { - String request = makeRequest("test_actor_id", "test_op_id", "test_target", "test_clName"); + String request = makeGuardRequest("test_actor_id", "test_op_id", "test_target", "test_clName"); + DecisionResponse decision = sendRequest(request); + assertEquals("Permit", decision.getStatus()); + + request = makeGuardRequest("test_actor_id", "test_op_id", "test_target", "denyGuard"); + decision = sendRequest(request); + assertEquals("Deny", decision.getStatus()); + } + + @Test + public void testConfigure() throws CoderException { + // test retrieving a policy + String request = makeConfigureRequest("policy-id", "test-policy"); + DecisionResponse decision = sendRequest(request); + assertNotNull(decision.getPolicies()); + assertThat(decision.getPolicies()).containsKey("test-policy"); + + // test no policy found + request = makeConfigureRequest("policy-id", "nonexistent"); + decision = sendRequest(request); + assertNotNull(decision.getPolicies()); + assertThat(decision.getPolicies()).doesNotContainKey("nonexistent"); + + // test unsupported operation + request = makeConfigureRequest("policy-type", "test"); + decision = sendRequest(request); + assertEquals("resource must contain policy-id key", decision.getMessage()); + } + + @Test + public void testConfigureMissingFile() throws CoderException { + // test retrieving a policy + String request = makeConfigureRequest("policy-id", "bogus-policy"); + DecisionResponse decision = sendRequest(request); + assertNotNull(decision.getPolicies()); + assertEquals("cannot read policy simulator file", decision.getMessage()); + } + + @Test + public void testConfigureInvalidJson() throws CoderException { + // test retrieving a policy + String request = makeConfigureRequest("policy-id", "invalid-policy"); + DecisionResponse decision = sendRequest(request); + assertNotNull(decision.getPolicies()); + assertEquals("cannot decode policy", decision.getMessage()); + } + + @Test + public void testUnknownAction() throws CoderException { + String request = makeGuardRequest("test_actor_id", "test_op_id", "test_target", "test_clName"); + request = request.replace("guard", "bogus-action"); + DecisionResponse decision = sendRequest(request); + assertThat(decision.getStatus()).isNull(); + assertThat(decision.getMessage()).isEqualTo("unsupported action: bogus-action"); + } + + private DecisionResponse sendRequest(String request) throws CoderException { String url = "http://localhost:" + Util.XACMLSIM_SERVER_PORT + "/policy/pdpx/v1/decision"; Pair response = new RestManager().post(url, "testUname", "testPass", null, "application/json", request); - assertNotNull(response); - assertNotNull(response.getLeft()); - assertNotNull(response.getRight()); - DecisionResponse decision = coder.decode(response.getRight(), DecisionResponse.class); - assertEquals("Permit", decision.getStatus()); - - request = makeRequest("test_actor_id", "test_op_id", "test_target", "denyGuard"); - response = new RestManager().post(url, "testUname", "testPass", null, "application/json", request); + // verify the response isn't null assertNotNull(response); assertNotNull(response.getLeft()); assertNotNull(response.getRight()); - decision = coder.decode(response.getRight(), DecisionResponse.class); - assertEquals("Deny", decision.getStatus()); + + return coder.decode(response.getRight(), DecisionResponse.class); } - private static String makeRequest(String actor, String recipe, String target, String clName) throws CoderException { - Map guard = new HashMap(); + private String makeGuardRequest(String actor, String recipe, String target, String clName) throws CoderException { + Map guard = new HashMap<>(); guard.put("actor", actor); guard.put("recipe", recipe); guard.put("target", target); guard.put("clname", clName); - Map resource = new HashMap(); + + Map resource = new HashMap<>(); resource.put("guard", guard); + + DecisionRequest request = new DecisionRequest(); + request.setAction("guard"); + request.setResource(resource); + + return coder.encode(request); + } + + private String makeConfigureRequest(String key, String val) throws CoderException { + Map resource = new HashMap<>(); + resource.put(key, val); + DecisionRequest request = new DecisionRequest(); + request.setAction("configure"); request.setResource(resource); return coder.encode(request); diff --git a/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.invalid-policy.json b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.invalid-policy.json new file mode 100644 index 000000000..5176a668d --- /dev/null +++ b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.invalid-policy.json @@ -0,0 +1,4 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_1_0", + "topology_template": { + "policies": [ diff --git a/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.test-policy.json b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.test-policy.json new file mode 100644 index 000000000..214a447da --- /dev/null +++ b/models-interactions/model-simulators/src/test/resources/org/onap/policy/simulators/xacml/xacml.configure.test-policy.json @@ -0,0 +1,22 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_1_0", + "topology_template": { + "policies": [ + { + "test-policy": { + "type": "onap.policies.monitoring.test", + "type_version": "1.0.0", + "version": "1.0.0", + "name": "test-policy", + "metadata": { + "policy-id": "test-policy", + "policy-version": 1 + }, + "properties": { + "test": "test" + } + } + } + ] + } +} -- cgit 1.2.3-korg