From 59c38b6b3dfbd43c876f85ffb1e4b484951ced44 Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Fri, 15 Mar 2019 14:30:00 -0400 Subject: Started with test decision JSON objects. Added new Policy Finder Factory that ONAP will use and got the code working with new policy/models (see other review which will have to be merged first). Added some new conversion methods to convert from a Xacml request to an Onap request. Added some property methods for XACML Properties objects and JUnit tests. Started filling in some Guard application details and combining code. Issue-ID: POLICY-1602 Change-Id: I5235b74f3b036dcf05779b655a03ac290d594354 Signed-off-by: Pamela Dragosh --- .../pdp/application/guard/GuardPdpApplication.java | 172 ++++++++++++++++++++- ...lication.common.XacmlApplicationServiceProvider | 1 + .../guard/src/main/resources/RootGuardPolicy.xml | 28 ++++ .../application/guard/GuardPdpApplicationTest.java | 166 +++++++++++++++----- 4 files changed, 327 insertions(+), 40 deletions(-) create mode 100644 applications/guard/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider create mode 100644 applications/guard/src/main/resources/RootGuardPolicy.xml (limited to 'applications/guard/src') diff --git a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java index e8a51136..2717c279 100644 --- a/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java +++ b/applications/guard/src/main/java/org/onap/policy/xacml/pdp/application/guard/GuardPdpApplication.java @@ -22,18 +22,36 @@ package org.onap.policy.xacml.pdp.application.guard; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.util.XACMLPolicyWriter; import com.google.common.collect.Lists; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; -import org.json.JSONObject; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; + +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException; +import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConverter; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; /** * This class implements the onap.policies.controlloop.Guard policy implementations. @@ -41,12 +59,14 @@ import org.slf4j.LoggerFactory; * @author pameladragosh * */ -public class GuardPdpApplication implements XacmlApplicationServiceProvider { +public class GuardPdpApplication implements ToscaPolicyConverter, XacmlApplicationServiceProvider { private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplication.class); private static final String STRING_VERSION100 = "1.0.0"; private Map supportedPolicyTypes = new HashMap<>(); private Path pathForData; + private Properties pdpProperties = null; + private PDPEngine pdpEngine = null; /** Constructor. * @@ -69,10 +89,26 @@ public class GuardPdpApplication implements XacmlApplicationServiceProvider { @Override public void initialize(Path pathForData) { // - // Save the path + // Save our path // this.pathForData = pathForData; LOGGER.debug("New Path is {}", this.pathForData.toAbsolutePath()); + // + // Look for and load the properties object + // + try { + pdpProperties = XacmlPolicyUtils.loadXacmlProperties(XacmlPolicyUtils.getPropertiesPath(pathForData)); + LOGGER.debug("{}", pdpProperties); + } catch (IOException e) { + LOGGER.error("{}", e); + } + // + // Create an engine + // + PDPEngine newEngine = XacmlPolicyUtils.createEngine(pdpProperties); + if (newEngine != null) { + pdpEngine = newEngine; + } } @Override @@ -97,11 +133,139 @@ public class GuardPdpApplication implements XacmlApplicationServiceProvider { @Override public void loadPolicies(Map toscaPolicies) { + try { + // + // Convert the policies first + // + List listPolicies = this.convertPolicies(toscaPolicies); + if (listPolicies.isEmpty()) { + throw new ToscaPolicyConversionException("Converted 0 policies"); + } + } catch (ToscaPolicyConversionException e) { + LOGGER.error("Failed to loadPolicies {}", e); + } + } + + @Override + public DecisionResponse makeDecision(DecisionRequest request) { + // + // Convert to a XacmlRequest + // + Request xacmlRequest = this.convertRequest(request); + // + // Now get a decision + // + Response xacmlResponse = this.xacmlDecision(xacmlRequest); + // + // Convert to a DecisionResponse + // + return this.convertResponse(xacmlResponse); + } + + @Override + public List convertPolicies(InputStream isToscaPolicy) throws ToscaPolicyConversionException { + // + // Have snakeyaml parse the object + // + Yaml yaml = new Yaml(); + Map toscaObject = yaml.load(isToscaPolicy); + // + // Return the policies + // + return scanAndConvertPolicies(toscaObject); + } + + @Override + public List convertPolicies(Map toscaObject) throws ToscaPolicyConversionException { + // + // Return the policies + // + return scanAndConvertPolicies(toscaObject); } @Override - public JSONObject makeDecision(JSONObject jsonSchema) { + public Request convertRequest(DecisionRequest request) { + // TODO Auto-generated method stub return null; } + @Override + public DecisionResponse convertResponse(Response response) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + private List scanAndConvertPolicies(Map toscaObject) + throws ToscaPolicyConversionException { + // + // Our return object + // + List scannedPolicies = new ArrayList<>(); + // + // Iterate each of the Policies + // + List policies = (List) toscaObject.get("policies"); + for (Object policyObject : policies) { + // + // Get the contents + // + LOGGER.debug("Found policy {}", policyObject.getClass()); + Map policyContents = (Map) policyObject; + for (Entry entrySet : policyContents.entrySet()) { + LOGGER.debug("Entry set {}", entrySet); + // + // Convert this policy + // + PolicyType policy = this.convertPolicy(entrySet); + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + XACMLPolicyWriter.writePolicyFile(os, policy); + LOGGER.debug("{}", os); + } catch (IOException e) { + LOGGER.error("Failed to convert {}", e); + } + // + // Convert and add in the new policy + // + scannedPolicies.add(policy); + } + } + + return scannedPolicies; + } + + private PolicyType convertPolicy(Entry entrySet) throws ToscaPolicyConversionException { + + return null; + } + + /** + * Make a decision call. + * + * @param request Incoming request object + * @return Response object + */ + private synchronized Response xacmlDecision(Request request) { + // + // This is what we need to return + // + Response response = null; + // + // Track some timing + // + long timeStart = System.currentTimeMillis(); + try { + response = this.pdpEngine.decide(request); + } catch (PDPException e) { + LOGGER.error("Xacml PDP Engine failed {}", e); + } finally { + // + // Track the end of timing + // + long timeEnd = System.currentTimeMillis(); + LOGGER.info("Elapsed Time: {}ms", (timeEnd - timeStart)); + } + return response; + } + } diff --git a/applications/guard/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider b/applications/guard/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider new file mode 100644 index 00000000..93084459 --- /dev/null +++ b/applications/guard/src/main/resources/META-INF/services/org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider @@ -0,0 +1 @@ +org.onap.policy.xacml.pdp.application.guard.GuardPdpApplication \ No newline at end of file diff --git a/applications/guard/src/main/resources/RootGuardPolicy.xml b/applications/guard/src/main/resources/RootGuardPolicy.xml new file mode 100644 index 00000000..f9f47265 --- /dev/null +++ b/applications/guard/src/main/resources/RootGuardPolicy.xml @@ -0,0 +1,28 @@ + + + The root policy for supporting onap.Guard policies. + + + + + guard + + + + + + + + Default is to allow a permit - returning 0 obligations + + + + + + \ No newline at end of file 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 656c7275..ae4193d3 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 @@ -25,37 +25,46 @@ 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.std.annotations.XACMLAction; -import com.att.research.xacml.std.annotations.XACMLRequest; -import com.att.research.xacml.std.annotations.XACMLResource; -import com.att.research.xacml.std.annotations.XACMLSubject; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.io.Files; +import com.google.gson.Gson; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Iterator; +import java.util.Properties; +import java.util.ServiceLoader; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.onap.policy.common.utils.resources.TextFileUtils; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.serialization.DecisionRequestMessageBodyHandler; +import org.onap.policy.models.decisions.serialization.DecisionResponseMessageBodyHandler; +import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class GuardPdpApplicationTest { - @ClassRule - public static final TemporaryFolder policyFolder = new TemporaryFolder(); - - /** - * This is a simple annotation class to simulate - * requests coming in. - */ - @XACMLRequest(ReturnPolicyIdList = true) - public class MyXacmlRequest { - - @XACMLSubject(includeInResults = true) - String onapName = "Drools"; + private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplicationTest.class); + private static Properties properties = new Properties(); + private static File propertiesFile; + private static XacmlApplicationServiceProvider service; + private static DecisionRequest requestSinglePolicy; - @XACMLResource(includeInResults = true) - String resource = "onap.policies.Guard"; + private static Gson gsonDecisionRequest; + private static Gson gsonDecisionResponse; - @XACMLAction() - String action = "guard"; - } + @ClassRule + public static final TemporaryFolder policyFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { @@ -65,32 +74,117 @@ public class GuardPdpApplicationTest { @Test public void testBasics() { assertThatCode(() -> { - GuardPdpApplication guard = new GuardPdpApplication(); // - // Set the path + // Create our Gson builder + // + gsonDecisionRequest = new DecisionRequestMessageBodyHandler().getGson(); + gsonDecisionResponse = new DecisionResponseMessageBodyHandler().getGson(); + // + // Load Single Decision Request + // + requestSinglePolicy = gsonDecisionRequest.fromJson( + TextFileUtils + .getTextFileAsString("../../main/src/test/resources/decisions/decision.single.input.json"), + DecisionRequest.class); // - guard.initialize(policyFolder.getRoot().toPath()); + // Copy all the properties and root policies to the temporary folder // - // Application name + try (InputStream is = new FileInputStream("src/test/resources/xacml.properties")) { + // + // Load it in + // + properties.load(is); + propertiesFile = policyFolder.newFile("xacml.properties"); + // + // Copy the root policies + // + for (String root : XACMLProperties.getRootPolicyIDs(properties)) { + // + // Get a file + // + Path rootPath = Paths.get(properties.getProperty(root + ".file")); + LOGGER.debug("Root file {} {}", rootPath, rootPath.getFileName()); + // + // Construct new file name + // + File newRootPath = policyFolder.newFile(rootPath.getFileName().toString()); + // + // Copy it + // + Files.copy(rootPath.toFile(), newRootPath); + assertThat(newRootPath).exists(); + // + // Point to where the new policy is in the temp dir + // + properties.setProperty(root + ".file", newRootPath.getAbsolutePath()); + } + try (OutputStream os = new FileOutputStream(propertiesFile.getAbsolutePath())) { + properties.store(os, ""); + assertThat(propertiesFile).exists(); + } + } // - assertThat(guard.applicationName()).isNotEmpty(); + // Load service + // + ServiceLoader applicationLoader = + ServiceLoader.load(XacmlApplicationServiceProvider.class); + // + // Iterate through them - I could store the object as + // XacmlApplicationServiceProvider pointer. + // + // Try this later. + // + StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator()); + Iterator iterator = applicationLoader.iterator(); + while (iterator.hasNext()) { + XacmlApplicationServiceProvider application = iterator.next(); + // + // Is it our service? + // + if (application instanceof GuardPdpApplication) { + // + // Should be the first and only one + // + assertThat(service).isNull(); + service = application; + } + strDump.append(application.applicationName()); + strDump.append(" supports "); + strDump.append(application.supportedPolicyTypes()); + strDump.append(System.lineSeparator()); + } + LOGGER.debug("{}", strDump); + // + // Tell it to initialize based on the properties file + // we just built for it. + // + service.initialize(propertiesFile.toPath().getParent()); + // + // Make sure there's an application name + // + assertThat(service.applicationName()).isNotEmpty(); // // Decisions // - assertThat(guard.actionDecisionsSupported().size()).isEqualTo(1); - assertThat(guard.actionDecisionsSupported()).contains("guard"); + assertThat(service.actionDecisionsSupported().size()).isEqualTo(1); + assertThat(service.actionDecisionsSupported()).contains("guard"); // - // Supported policy types + // Ensure it has the supported policy types and + // can support the correct policy types. // - assertThat(guard.supportedPolicyTypes()).isNotEmpty(); - assertThat(guard.supportedPolicyTypes().size()).isEqualTo(2); - assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0")) + assertThat(service.supportedPolicyTypes()).isNotEmpty(); + assertThat(service.supportedPolicyTypes().size()).isEqualTo(2); + assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.0")) .isTrue(); - assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1")) + assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.FrequencyLimiter", "1.0.1")) .isFalse(); - assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.0")).isTrue(); - assertThat(guard.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.1")).isFalse(); - assertThat(guard.canSupportPolicyType("onap.foo", "1.0.1")).isFalse(); + assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.0")).isTrue(); + assertThat(service.canSupportPolicyType("onap.policies.controlloop.guard.MinMax", "1.0.1")).isFalse(); + assertThat(service.canSupportPolicyType("onap.foo", "1.0.1")).isFalse(); + // + // Ensure it supports decisions + // + assertThat(service.actionDecisionsSupported()).contains("guard"); }).doesNotThrowAnyException(); } } -- cgit 1.2.3-korg