bump poms to 2.1.4-SNAPSHOT
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / XacmlPolicyUtils.java
index ca327b9..6f2a9f0 100644 (file)
 package org.onap.policy.pdp.xacml.application.common;
 
 import com.att.research.xacml.api.Identifier;
-import com.att.research.xacml.api.pdp.PDPEngine;
-import com.att.research.xacml.api.pdp.PDPEngineFactory;
-import com.att.research.xacml.util.FactoryException;
 import com.att.research.xacml.util.XACMLProperties;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 import java.util.StringJoiner;
@@ -51,6 +52,9 @@ import org.slf4j.LoggerFactory;
 public class XacmlPolicyUtils {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPolicyUtils.class);
+
+    public static final String XACML_PROPERTY_FILE = "xacml.properties";
+
     private static final String DOT_FILE_SUFFIX = ".file";
     private static final String NOT_FOUND_MESSAGE = "NOT FOUND";
 
@@ -145,6 +149,40 @@ public class XacmlPolicyUtils {
         return rootPolicy;
     }
 
+    /**
+     * Adds in the root policy to the PDP properties object.
+     *
+     * @param properties Input properties
+     * @param rootPolicyPath Path to the root policy file
+     * @return Properties object
+     */
+    public static Properties addRootPolicy(Properties properties, Path rootPolicyPath) {
+        //
+        // Get the current set of referenced policy ids
+        //
+        Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
+        //
+        // Construct a unique id
+        //
+        int id = 1;
+        while (true) {
+            String refId = "root" + id;
+            if (rootPolicies.contains(refId)) {
+                id++;
+            } else {
+                rootPolicies.add(refId);
+                properties.put(refId + DOT_FILE_SUFFIX, rootPolicyPath.toAbsolutePath().toString());
+                break;
+            }
+        }
+        //
+        // Set the new comma separated list
+        //
+        properties.setProperty(XACMLProperties.PROP_ROOTPOLICIES,
+                rootPolicies.stream().collect(Collectors.joining(",")));
+        return properties;
+    }
+
     /**
      * Adds in the referenced policy to the PDP properties object.
      *
@@ -179,6 +217,50 @@ public class XacmlPolicyUtils {
         return properties;
     }
 
+    /**
+     * Removes a root policy from the Properties object. Both in the line
+     * that identifies the policy and the .file property that points to the path.
+     *
+     * @param properties Input Properties object to remove
+     * @param rootPolicyPath The policy file path
+     * @return Properties object
+     */
+    public static Properties removeRootPolicy(Properties properties, Path rootPolicyPath) {
+        //
+        // Get the current set of referenced policy ids
+        //
+        StringJoiner join = new StringJoiner(",");
+        boolean found = false;
+        Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties);
+        for (String refPolicy : rootPolicies) {
+            String refPolicyFile = refPolicy + DOT_FILE_SUFFIX;
+            //
+            // If the key and value match, then it will return true
+            //
+            if (properties.remove(refPolicyFile, rootPolicyPath.toString())) {
+                //
+                // Record that we actually removed it
+                //
+                found = true;
+            } else {
+                //
+                // Retain it
+                //
+                join.add(refPolicy);
+            }
+        }
+        //
+        // Did we remove it?
+        //
+        if (found) {
+            //
+            // Now update the list of referenced properties
+            //
+            properties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, join.toString());
+        }
+        return properties;
+    }
+
     /**
      * Removes a referenced policy from the Properties object. Both in the line
      * that identifies the policy and the .file property that points to the path.
@@ -288,10 +370,16 @@ public class XacmlPolicyUtils {
      * @throws IOException If unable to read file
      */
     public static Properties loadXacmlProperties(Path propertyPath) throws IOException {
-        LOGGER.debug("Loading xacml properties {}", propertyPath);
+        LOGGER.info("Loading xacml properties {}", propertyPath);
         try (InputStream is = Files.newInputStream(propertyPath)) {
             Properties properties = new Properties();
             properties.load(is);
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info("Loaded xacml properties {} {}", System.lineSeparator(), properties);
+                for (Entry<Object, Object> entrySet : properties.entrySet()) {
+                    LOGGER.info("{} -> {}", entrySet.getKey(), entrySet.getValue());
+                }
+            }
             return properties;
         }
     }
@@ -302,6 +390,9 @@ public class XacmlPolicyUtils {
      * @throws IOException If unable to store the file.
      */
     public static void storeXacmlProperties(Properties properties, Path propertyPath) throws IOException {
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("Storing xacml properties {} {} {}", properties, System.lineSeparator(), propertyPath);
+        }
         try (OutputStream os = Files.newOutputStream(propertyPath)) {
             String strComments = "#";
             properties.store(os, strComments);
@@ -315,26 +406,94 @@ public class XacmlPolicyUtils {
      * @return Path to rootPath/xacml.properties file
      */
     public static Path getPropertiesPath(Path rootPath) {
-        return Paths.get(rootPath.toAbsolutePath().toString(), "xacml.properties");
+        return Paths.get(rootPath.toAbsolutePath().toString(), XACML_PROPERTY_FILE);
     }
 
+    @FunctionalInterface
+    public interface FileCreator {
+        public File createAFile(String filename) throws IOException;
+
+    }
 
     /**
-     * Creates an instance of PDP engine given the Properties object.
+     * Copies a xacml.properties file to another location and all the policies defined within it.
      *
-     * @param properties Incoming Properties object
-     * @return PDPEngine instance or null if failed
+     * @param propertiesPath Path to an existing properties file
+     * @param properties Properties object
+     * @param creator A callback that can create files. Allows JUnit test to pass Temporary folder
+     * @return File object that points to new Properties file
+     * @throws IOException Could not read/write files
      */
-    public static PDPEngine createEngine(Properties properties) {
+    public static File copyXacmlPropertiesContents(String propertiesPath, Properties properties,
+            FileCreator creator) throws IOException {
         //
-        // Now initialize the XACML PDP Engine
+        // Open the properties file
         //
-        try {
-            PDPEngineFactory factory = PDPEngineFactory.newInstance();
-            return factory.newEngine(properties);
-        } catch (FactoryException e) {
-            LOGGER.error("Failed to create XACML PDP Engine {}", e);
+        try (InputStream is = new FileInputStream(propertiesPath)) {
+            //
+            // Load in the properties
+            //
+            properties.load(is);
+            //
+            // Now we create a new xacml.properties in the temporary folder location
+            //
+            File propertiesFile = creator.createAFile(XACML_PROPERTY_FILE);
+            //
+            // Iterate through any root policies defined
+            //
+            for (String root : XACMLProperties.getRootPolicyIDs(properties)) {
+                //
+                // Get a file
+                //
+                Path rootPath = Paths.get(properties.getProperty(root + DOT_FILE_SUFFIX));
+                LOGGER.info("Root file {} {}", rootPath, rootPath.getFileName());
+                //
+                // Construct new path for the root policy
+                //
+                File newRootPath = creator.createAFile(rootPath.getFileName().toString());
+                //
+                // Copy the policy file to the temporary folder
+                //
+                com.google.common.io.Files.copy(rootPath.toFile(), newRootPath);
+                //
+                // Change the properties object to point to where the new policy is
+                // in the temporary folder
+                //
+                properties.setProperty(root + DOT_FILE_SUFFIX, newRootPath.getAbsolutePath());
+            }
+            //
+            // Iterate through any referenced policies defined
+            //
+            for (String referenced : XACMLProperties.getReferencedPolicyIDs(properties)) {
+                //
+                // Get a file
+                //
+                Path refPath = Paths.get(properties.getProperty(referenced + DOT_FILE_SUFFIX));
+                LOGGER.info("Referenced file {} {}", refPath, refPath.getFileName());
+                //
+                // Construct new path for the root policy
+                //
+                File newReferencedPath = creator.createAFile(refPath.getFileName().toString());
+                //
+                // Copy the policy file to the temporary folder
+                //
+                com.google.common.io.Files.copy(refPath.toFile(), newReferencedPath);
+                //
+                // Change the properties object to point to where the new policy is
+                // in the temporary folder
+                //
+                properties.setProperty(referenced + DOT_FILE_SUFFIX, newReferencedPath.getAbsolutePath());
+            }
+            //
+            // Save the new properties file to the temporary folder
+            //
+            try (OutputStream os = new FileOutputStream(propertiesFile.getAbsolutePath())) {
+                properties.store(os, "");
+            }
+            //
+            // Return the new path to the properties folder
+            //
+            return propertiesFile;
         }
-        return null;
     }
 }