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;
-import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
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 lombok.Getter;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onap.policy.common.endpoints.parameters.RestServerParameters;
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;
+ @Getter
+ private RestServerParameters policyApiParameters;
private Properties pdpProperties = null;
private PDPEngine pdpEngine = null;
+ private Map<ToscaPolicy, Path> mapLoadedPolicies = new HashMap<>();
public StdXacmlApplicationServiceProvider() {
super();
}
@Override
- public void initialize(Path pathForData) {
+ public void initialize(Path pathForData, RestServerParameters policyApiParameters)
+ throws XacmlApplicationException {
//
// Save our path
//
this.pathForData = pathForData;
- LOGGER.debug("New Path is {}", this.pathForData.toAbsolutePath());
+ LOGGER.info("New Path is {}", this.pathForData.toAbsolutePath());
+ //
+ // Save our params
+ //
+ this.policyApiParameters = policyApiParameters;
//
// Look for and load the properties object
//
try {
pdpProperties = XacmlPolicyUtils.loadXacmlProperties(XacmlPolicyUtils.getPropertiesPath(pathForData));
- LOGGER.debug("{}", pdpProperties);
+ LOGGER.info("{}", pdpProperties);
} catch (IOException e) {
- LOGGER.error("{}", e);
+ throw new XacmlApplicationException("Failed to load " + XacmlPolicyUtils.XACML_PROPERTY_FILE, e);
}
//
// Create an engine
}
@Override
- public List<String> supportedPolicyTypes() {
- return Collections.emptyList();
+ public List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
+ throw new UnsupportedOperationException("Please override and implement supportedPolicyTypes");
}
@Override
- public boolean canSupportPolicyType(String policyType, String policyTypeVersion) {
- return false;
+ public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+ throw new UnsupportedOperationException("Please override and implement canSupportPolicyType");
}
@Override
- public void loadPolicies(Map<String, Object> toscaPolicies) {
- throw new UnsupportedOperationException("Please override and implement loadPolicies");
+ 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.isInfoEnabled()) {
+ LOGGER.info("Xacml Policy is {}{}", XacmlPolicyUtils.LINE_SEPARATOR,
+ new String(Files.readAllBytes(refPath), StandardCharsets.UTF_8));
+ }
+ //
+ // 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 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, e);
+ }
+ //
+ // 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) {
+ public Pair<DecisionResponse, Response> makeDecision(DecisionRequest request,
+ Map<String, String[]> requestQueryParams) {
+ //
+ // Convert to a XacmlRequest
//
- // We should have a standard error response to return
+ Request xacmlRequest = this.getTranslator().convertRequest(request);
//
- return null;
+ // Now get a decision
+ //
+ Response xacmlResponse = this.xacmlDecision(xacmlRequest);
+ //
+ // Convert to a DecisionResponse
+ //
+ return Pair.of(this.getTranslator().convertResponse(xacmlResponse), xacmlResponse);
+ }
+
+ protected abstract ToscaPolicyTranslator getTranslator(String type);
+
+ protected ToscaPolicyTranslator getTranslator() {
+ return this.getTranslator("");
}
protected synchronized PDPEngine getEngine() {
}
protected synchronized Properties getProperties() {
- return new Properties(pdpProperties);
+ Properties newProperties = new Properties();
+ newProperties.putAll(pdpProperties);
+ return newProperties;
}
protected synchronized Path getDataPath() {
return pathForData;
}
- /**
- * Load properties from given file.
- *
- * @throws IOException If unable to read file
- */
- protected synchronized Properties loadXacmlProperties() throws IOException {
- LOGGER.debug("Loading xacml properties {}", pathForData);
- try (InputStream is = Files.newInputStream(pathForData)) {
- Properties properties = new Properties();
- properties.load(is);
- return properties;
- }
- }
-
- /**
- * Stores the XACML Properties to the given file location.
- *
- * @throws IOException If unable to store the file.
- */
- protected synchronized void storeXacmlProperties() throws IOException {
- try (OutputStream os = Files.newOutputStream(pathForData)) {
- String strComments = "#";
- pdpProperties.store(os, strComments);
- }
- }
-
- /**
- * Appends 'xacml.properties' to a root Path object
- *
- * @return Path to rootPath/xacml.properties file
- */
- protected synchronized Path getPropertiesPath() {
- return Paths.get(pathForData.toAbsolutePath().toString(), "xacml.properties");
- }
-
/**
* Creates an instance of PDP engine given the Properties object.
*/
// Now initialize the XACML PDP Engine
//
try {
- PDPEngineFactory factory = PDPEngineFactory.newInstance();
+ PDPEngineFactory factory = getPdpEngineFactory();
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);
return response;
}
+ // these may be overridden by junit tests
+
+ protected PDPEngineFactory getPdpEngineFactory() throws FactoryException {
+ return PDPEngineFactory.newInstance();
+ }
}