Merge "Add Control Loop Coordination policy."
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdXacmlApplicationServiceProvider.java
index 19d8d82..95a642e 100644 (file)
@@ -28,6 +28,7 @@ import com.att.research.xacml.api.pdp.PDPEngine;
 import com.att.research.xacml.api.pdp.PDPEngineFactory;
 import com.att.research.xacml.api.pdp.PDPException;
 import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLPolicyWriter;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -36,25 +37,32 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+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.models.tosca.authorative.concepts.ToscaPolicy;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
+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.XacmlApplicationException;
 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;
 
-public class StdXacmlApplicationServiceProvider implements XacmlApplicationServiceProvider {
+public abstract class StdXacmlApplicationServiceProvider implements XacmlApplicationServiceProvider {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(StdXacmlApplicationServiceProvider.class);
     private Path pathForData = null;
     private Properties pdpProperties = null;
     private PDPEngine pdpEngine = null;
+    private Map<ToscaPolicy, Path> mapLoadedPolicies = new HashMap<>();
 
     public StdXacmlApplicationServiceProvider() {
         super();
@@ -110,25 +118,147 @@ public class StdXacmlApplicationServiceProvider implements XacmlApplicationServi
 
     @Override
     public List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
-        return Collections.emptyList();
+        throw new UnsupportedOperationException("Please override and implement supportedPolicyTypes");
     }
 
     @Override
     public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
-        return false;
+        throw new UnsupportedOperationException("Please override and implement canSupportPolicyType");
+    }
+
+    @Override
+    public synchronized boolean loadPolicy(ToscaPolicy toscaPolicy) {
+        try {
+            //
+            // Convert the policies first
+            //
+            PolicyType xacmlPolicy = this.getTranslator(toscaPolicy.getType())
+                .convertPolicy(toscaPolicy);
+            if (xacmlPolicy == null) {
+                throw new ToscaPolicyConversionException("Failed to convert policy");
+            }
+            //
+            // Create a copy of the properties object
+            //
+            Properties newProperties = this.getProperties();
+            //
+            // Construct the filename
+            //
+            Path refPath = XacmlPolicyUtils.constructUniquePolicyFilename(xacmlPolicy, this.getDataPath());
+            //
+            // Write the policy to disk
+            // Maybe check for an error
+            //
+            XACMLPolicyWriter.writePolicyFile(refPath, xacmlPolicy);
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("Xacml Policy is {}{}", System.lineSeparator(), new String(Files.readAllBytes(refPath)));
+            }
+            //
+            // Add root policy to properties object
+            //
+            XacmlPolicyUtils.addRootPolicy(newProperties, refPath);
+            //
+            // Write the properties to disk
+            //
+            XacmlPolicyUtils.storeXacmlProperties(newProperties,
+                    XacmlPolicyUtils.getPropertiesPath(this.getDataPath()));
+            //
+            // Reload the engine
+            //
+            this.createEngine(newProperties);
+            //
+            // Save the properties
+            //
+            this.pdpProperties = newProperties;
+            //
+            // Save in our map
+            //
+            this.mapLoadedPolicies.put(toscaPolicy, refPath);
+        } catch (IOException | ToscaPolicyConversionException e) {
+            LOGGER.error("Failed to loadPolicies {}", e);
+            return false;
+        }
+        return true;
     }
 
     @Override
-    public void loadPolicies(Map<String, Object> toscaPolicies) throws XacmlApplicationException {
-        throw new UnsupportedOperationException("Please override and implement loadPolicies");
+    public synchronized boolean unloadPolicy(ToscaPolicy toscaPolicy) throws XacmlApplicationException {
+        //
+        // Find it in our map
+        //
+        Path refPolicy = this.mapLoadedPolicies.get(toscaPolicy);
+        if (refPolicy == null) {
+            LOGGER.error("Failed to find ToscaPolicy {} in our map size {}", toscaPolicy.getMetadata(),
+                    this.mapLoadedPolicies.size());
+            return false;
+        }
+        //
+        // Create a copy of the properties object
+        //
+        Properties newProperties = this.getProperties();
+        //
+        // Remove it from the properties
+        //
+        XacmlPolicyUtils.removeRootPolicy(newProperties, refPolicy);
+        //
+        // We can delete the file
+        //
+        try {
+            Files.delete(refPolicy);
+        } catch (IOException e) {
+            LOGGER.error("Failed to delete policy {} from disk {}", toscaPolicy.getMetadata(),
+                    refPolicy.toAbsolutePath().toString(), e);
+        }
+        //
+        // Write the properties to disk
+        //
+        try {
+            XacmlPolicyUtils.storeXacmlProperties(newProperties,
+                    XacmlPolicyUtils.getPropertiesPath(this.getDataPath()));
+        } catch (IOException e) {
+            LOGGER.error("Failed to save the properties to disk {}", newProperties);
+        }
+        //
+        // Reload the engine
+        //
+        this.createEngine(newProperties);
+        //
+        // Save the properties
+        //
+        this.pdpProperties = newProperties;
+        //
+        // Save in our map
+        //
+        if (this.mapLoadedPolicies.remove(toscaPolicy) == null) {
+            LOGGER.error("Failed to remove toscaPolicy {} from internal map size {}", toscaPolicy.getMetadata(),
+                    this.mapLoadedPolicies.size());
+        }
+        //
+        // Not sure if any of the errors above warrant returning false
+        //
+        return true;
     }
 
     @Override
     public DecisionResponse makeDecision(DecisionRequest request) {
         //
-        // We should have a standard error response to return
+        // Convert to a XacmlRequest
         //
-        return null;
+        Request xacmlRequest = this.getTranslator().convertRequest(request);
+        //
+        // Now get a decision
+        //
+        Response xacmlResponse = this.xacmlDecision(xacmlRequest);
+        //
+        // Convert to a DecisionResponse
+        //
+        return this.getTranslator().convertResponse(xacmlResponse);
+    }
+
+    protected abstract ToscaPolicyTranslator getTranslator(String type);
+
+    protected ToscaPolicyTranslator getTranslator() {
+        return this.getTranslator("");
     }
 
     protected synchronized PDPEngine getEngine() {
@@ -136,7 +266,9 @@ public class StdXacmlApplicationServiceProvider implements XacmlApplicationServi
     }
 
     protected synchronized Properties getProperties() {
-        return new Properties(pdpProperties);
+        Properties newProperties = new Properties();
+        newProperties.putAll(pdpProperties);
+        return newProperties;
     }
 
     protected synchronized Path getDataPath() {
@@ -190,7 +322,6 @@ public class StdXacmlApplicationServiceProvider implements XacmlApplicationServi
             PDPEngine engine = factory.newEngine(properties);
             if (engine != null) {
                 this.pdpEngine = engine;
-                this.pdpProperties = new Properties(properties);
             }
         } catch (FactoryException e) {
             LOGGER.error("Failed to create XACML PDP Engine {}", e);