http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java new file mode 100755 index 0000000..6b44cda --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java @@ -0,0 +1,470 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPStatus; +import com.att.research.xacml.api.pap.PDPStatus.Status; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.api.pip.PIPEngine; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPFinderFactory; +import com.att.research.xacml.std.pap.StdPDPPIPConfig; +import com.att.research.xacml.std.pap.StdPDPPolicy; +import com.att.research.xacml.std.pap.StdPDPStatus; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory; +import com.google.common.base.Splitter; + +/** + * Does the work for loading policy and PIP configurations sent from the PAP servlet. + * + * + * @author pameladragosh + * + */ +public class XACMLPdpLoader { + private static final Log logger = LogFactory.getLog(XACMLPdpLoader.class); + + public static synchronized PDPEngine loadEngine(StdPDPStatus status, Properties policyProperties, Properties pipProperties) { + logger.info("loadEngine: " + policyProperties + " "+ pipProperties); + // + // First load our policies + // + try { + // + // Were we given some properties? + // + if (policyProperties == null) { + // + // On init we have no incoming configuration, so just + // Load our current saved configuration + // + policyProperties = new Properties(); + try (InputStream is = Files.newInputStream(getPDPPolicyCache())) { + policyProperties.load(is); + } + } + + // + // Get our policy cache up-to-date + // + // Side effects of this include: + // - downloading of policies from remote locations, and + // - creating new "<PolicyId>.file" properties for files existing local + // + XACMLPdpLoader.cachePolicies(policyProperties); + // + // Validate the policies + // + XACMLPdpLoader.validatePolicies(policyProperties, status); + if (logger.isDebugEnabled()) { + logger.debug("Status: " + status); + } + } catch (Exception e) { + String error = "Failed to load Policy Cache properties file: " + e.getMessage(); + logger.error(error, e); + status.addLoadError(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + } + // + // Load our PIP configuration + // + try { + // + // Were we given some properties to use? + // + if (pipProperties == null) { + // + // Load our current saved configuration + // + pipProperties = new Properties(); + try (InputStream is = Files.newInputStream(getPIPConfig())) { + pipProperties.load(is); + } + } + // + // Validate our PIP configurations + // + XACMLPdpLoader.validatePipConfiguration(pipProperties, status); + if (logger.isDebugEnabled()) { + logger.debug("Status: " + status); + } + } catch (Exception e) { + String error = "Failed to load/validate Pip Config properties file: " + e.getMessage(); + logger.error(error, e); + status.addLoadError(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + } + // + // Were they validated? + // + if (status.getStatus() == Status.LOAD_ERRORS) { + logger.error("there were load errors"); + return null; + } + // + // Reset our official properties the PDP factory + // uses to configure the PDP engine. + // + XACMLRest.loadXacmlProperties(policyProperties, pipProperties); + // + // Dump ALL our properties that we are trying to load + // + try { + logger.info(XACMLProperties.getProperties().toString()); + } catch (IOException e) { + logger.error("Failed to get XACML Properties", e); + } + // + // Now load the PDP engine + // + PDPEngineFactory factory = null; + PDPEngine engine = null; + try { + factory = PDPEngineFactory.newInstance(); + engine = factory.newEngine(); + logger.info("Loaded new PDP engine."); + status.setStatus(Status.UP_TO_DATE); + } catch (FactoryException e) { + String error = "Failed to create new PDP Engine"; + logger.error(error, e); + status.addLoadError(error); + } + return engine; + } + + public static synchronized void validatePolicies(Properties properties, StdPDPStatus status) throws PAPException { + Set<String> rootPolicies = XACMLProperties.getRootPolicyIDs(properties); + Set<String> refPolicies = XACMLProperties.getReferencedPolicyIDs(properties); + + for (String id : rootPolicies) { + loadPolicy(properties, status, id, true); + } + // remember which policies were root policies + status.addAllLoadedRootPolicies(status.getLoadedPolicies()); + + for (String id : refPolicies) { + loadPolicy(properties, status, id, false); + } + + logger.info("Loaded " + status.getLoadedPolicies().size() + " policies, failed to load " + status.getFailedPolicies().size() + " policies, " + + status.getLoadedRootPolicies().size() + " root policies"); + if (status.getLoadedRootPolicies().size() == 0) { + logger.warn("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests."); + status.addLoadWarning("NO ROOT POLICIES LOADED!!! Cannot serve PEP Requests."); + } + } + + public static synchronized void loadPolicy(Properties properties, StdPDPStatus status, String id, boolean isRoot) throws PAPException { + PolicyDef policy = null; + String location = null; + URI locationURI = null; + boolean isFile = false; + try { + location = properties.getProperty(id + ".file"); + if (location == null) { + location = properties.getProperty(id + ".url"); + if (location != null) { + // + // Construct the URL + // + locationURI = URI.create(location); + URL url = locationURI.toURL(); + URLConnection urlConnection = url.openConnection(); + urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + // + // Now construct the output file name + // + Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), id); + // + // Copy it to disk + // + try (FileOutputStream fos = new FileOutputStream(outFile.toFile())) { + IOUtils.copy(urlConnection.getInputStream(), fos); + } + // + // Now try to load + // + isFile = true; + try (InputStream fis = Files.newInputStream(outFile)) { + policy = DOMPolicyDef.load(fis); + } + // + // Save it + // + properties.setProperty(id + ".file", outFile.toAbsolutePath().toString()); + } + } else { + isFile = true; + locationURI = Paths.get(location).toUri(); + try (InputStream is = Files.newInputStream(Paths.get(location))) { + policy = DOMPolicyDef.load(is); + } + } + if (policy != null) { + status.addLoadedPolicy(new StdPDPPolicy(id, isRoot, locationURI, properties)); + logger.info("Loaded policy: " + policy.getIdentifier() + " version: " + policy.getVersion().stringValue()); + } else { + String error = "Failed to load policy " + location; + logger.error(error); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + status.addLoadError(error); + status.addFailedPolicy(new StdPDPPolicy(id, isRoot)); + } + } catch (Exception e) { + logger.error("Failed to load policy '" + id + "' from location '" + location + "'", e); + status.setStatus(PDPStatus.Status.LOAD_ERRORS); + status.addFailedPolicy(new StdPDPPolicy(id, isRoot)); + // + // Is it a file? + // + if (isFile) { + // + // Let's remove it + // + try { + logger.error("Corrupted policy file, deleting: " + location); + Files.delete(Paths.get(location)); + } catch (IOException e1) { + logger.error(e1); + } + } + throw new PAPException("Failed to load policy '" + id + "' from location '" + location + "'"); + } + } + + public static synchronized void validatePipConfiguration(Properties properties, StdPDPStatus status) throws PAPException { + try { + PIPFinderFactory factory = PIPFinderFactory.newInstance(properties); + if (factory == null) { + throw new FactoryException("Could not create PIP Finder Factory: " + properties.getProperty(XACMLProperties.PROP_PIPFINDERFACTORY)); + } + PIPFinder finder = factory.getFinder(properties); + // + // Check for this, although it should always return something + // + if (finder == null) { + logger.error("pip finder factory returned a null engine."); + throw new PIPException("Could not create PIP Finder"); + } else { + logger.info("Loaded PIP finder"); + } + for (PIPEngine engine : finder.getPIPEngines()) { + logger.info("Configured PIP Engine: " + engine.getName()); + StdPDPPIPConfig config = new StdPDPPIPConfig(); + config.setName(engine.getName()); + status.addLoadedPipConfig(config); + } + } catch (FactoryException | PIPException e) { + logger.error("validate PIP configuration failed: " + e.getLocalizedMessage()); + status.addLoadError(e.getLocalizedMessage()); + status.setStatus(Status.LOAD_ERRORS); + throw new PAPException(e); + } + } + + /** + * Iterates the policies defined in the props object to ensure they are loaded locally. + * Policies are searched for in the following order: + * - see if the current properties has a "<PolicyID>.file" entry and that file exists in the local directory + * - if not, see if the file exists in the local directory; if so create a ".file" property for it. + * - if not, get the "<PolicyID>.url" property and try to GET the policy from that location (and set the ".file" property) + * + * If the ".file" property is created, then true is returned to tell the caller that the props object changed. + * + * @param props + * @return true/false if anything was changed in the props object + * @throws PAPException + */ + public static synchronized boolean cachePolicies(Properties props) throws PAPException { + boolean changed = false; + String[] lists = new String[2]; + lists[0] = props.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists[1] = props.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); + for (String list : lists) { + // + // Check for a null or empty parameter + // + if (list == null || list.length() == 0) { + continue; + } + Iterable<String> policies = Splitter.on(',').trimResults().omitEmptyStrings().split(list); + for (String policy : policies) { + boolean policyExists = false; + + // First look for ".file" property and verify the file exists + String propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_FILE); + if (propLocation != null) { + // + // Does it exist? + // + policyExists = Files.exists(Paths.get(propLocation)); + if (policyExists == false) { + logger.warn("Policy file " + policy + " expected at " + propLocation + " does NOT exist."); + } + } + + // If ".file" property does not exist, try looking for the local file anyway + // (it might exist without having a ".file" property set for it) + if (policyExists == false) { + // + // Now construct the output file name + // + Path outFile = Paths.get(getPDPConfig().toAbsolutePath().toString(), policy); + // + // Double check to see if we pulled it at some point + // + policyExists = Files.exists(outFile); + if (policyExists) { + // + // Set the property so the PDP engine doesn't have + // to pull it from the URL but rather the FILE. + // + logger.info("Policy does exist: " + outFile.toAbsolutePath().toString()); + props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString()); + // + // Indicate that there were changes made to the properties + // + changed = true; + } else { + + // File does not exist locally, so we need to get it from the location given in the ".url" property (which MUST exist) + + // + // There better be a URL to retrieve it + // + propLocation = props.getProperty(policy + StdPolicyFinderFactory.PROP_URL); + if (propLocation != null) { + // + // Get it + // + URL url = null; + try { + // + // Create the URL + // + url = new URL(propLocation); + logger.info("Pulling " + url.toString()); + // + // Open the connection + // + URLConnection urlConnection = url.openConnection(); + urlConnection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + // + // Copy it to disk + // + try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(outFile.toFile())) { + IOUtils.copy(is, os); + } + // + // Now save it in the properties as a .file + // + logger.info("Pulled policy: " + outFile.toAbsolutePath().toString()); + props.setProperty(policy + StdPolicyFinderFactory.PROP_FILE, outFile.toAbsolutePath().toString()); + // + // Indicate that there were changes made to the properties + // + changed = true; + } catch (Exception e) { + if (e instanceof MalformedURLException) { + logger.error("Policy '" + policy + "' had bad URL in new configuration, URL='" + propLocation + "'"); + } else { + logger.error("Error while retrieving policy " + policy + " from URL " + url.toString() + ", e="+e); + } + } + } else { + logger.error("Policy " + policy + " does NOT exist and does NOT have a URL"); + } + } + } + } + } + return changed; + } + + public static synchronized Path getPDPPolicyCache() throws PAPException { + Path config = getPDPConfig(); + Path policyProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.policy.properties"); + if (Files.notExists(policyProperties)) { + logger.warn(policyProperties.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the file + // + try { + Files.createFile(policyProperties); + } catch (IOException e) { + logger.error("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString()); + throw new PAPException("Failed to create policy properties file: " + policyProperties.toAbsolutePath().toString()); + } + } + return policyProperties; + } + + public static synchronized Path getPIPConfig() throws PAPException { + Path config = getPDPConfig(); + Path pipConfigProperties = Paths.get(config.toAbsolutePath().toString(), "xacml.pip.properties"); + if (Files.notExists(pipConfigProperties)) { + logger.warn(pipConfigProperties.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the file + // + try { + Files.createFile(pipConfigProperties); + } catch (IOException e) { + logger.error("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString()); + throw new PAPException("Failed to create pip properties file: " + pipConfigProperties.toAbsolutePath().toString()); + } + } + return pipConfigProperties; + } + + public static synchronized Path getPDPConfig() throws PAPException { + Path config = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG)); + if (Files.notExists(config)) { + logger.warn(config.toAbsolutePath().toString() + " does NOT exist."); + // + // Try to create the directory + // + try { + Files.createDirectories(config); + } catch (IOException e) { + logger.error("Failed to create config directory: " + config.toAbsolutePath().toString(), e); + throw new PAPException("Failed to create config directory: " + config.toAbsolutePath().toString()); + } + } + return config; + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java new file mode 100755 index 0000000..3d232cf --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java @@ -0,0 +1,210 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.util.Properties; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.rest.XACMLPdpServlet.PutRequest; +import com.att.research.xacml.util.XACMLProperties; + +public class XACMLPdpRegisterThread implements Runnable { + private static final Log logger = LogFactory.getLog(XACMLPdpRegisterThread.class); + + public volatile boolean isRunning = false; + + public synchronized boolean isRunning() { + return this.isRunning; + } + + public synchronized void terminate() { + this.isRunning = false; + } + + /** + * + * This is our thread that runs on startup to tell the PAP server we are up-and-running. + * + */ + @Override + public void run() { + synchronized(this) { + this.isRunning = true; + } + boolean registered = false; + boolean interrupted = false; + int seconds; + try { + seconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_SLEEP)); + } catch (NumberFormatException e) { + logger.error("REGISTER_SLEEP: ", e); + seconds = 5; + } + if (seconds < 5) { + seconds = 5; + } + int retries; + try { + retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER_RETRIES)); + } catch (NumberFormatException e) { + logger.error("REGISTER_SLEEP: ", e); + retries = -1; + } + while (! registered && ! interrupted && this.isRunning()) { + HttpURLConnection connection = null; + try { + // + // Get the PAP Servlet URL + // + URL url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)); + logger.info("Registering with " + url.toString()); + boolean finished = false; + while (! finished) { + // + // Open up the connection + // + connection = (HttpURLConnection)url.openConnection(); + // + // Setup our method and headers + // + connection.setRequestMethod("POST"); + connection.setRequestProperty("Accept", "text/x-java-properties"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + connection.setRequestProperty(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID, XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID)); + connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + try { + // + // Send our current policy configuration + // + String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES); + lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES) + "\n"; + try (InputStream listsInputStream = new ByteArrayInputStream(lists.getBytes()); + InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig()); + OutputStream os = connection.getOutputStream()) { + IOUtils.copy(listsInputStream, os); + + // + // Send our current PIP configuration + // + IOUtils.copy(pipInputStream, os); + } + } catch (Exception e) { + logger.error("Failed to send property file", e); + } + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 204) { + logger.info("Success. We are configured correctly."); + finished = true; + registered = true; + } else if (connection.getResponseCode() == 200) { + logger.info("Success. We have a new configuration."); + Properties properties = new Properties(); + properties.load(connection.getInputStream()); + logger.info("New properties: " + properties.toString()); + // + // Queue it + // + // The incoming properties does NOT include urls + PutRequest req = new PutRequest(XACMLProperties.getPolicyProperties(properties, false), XACMLProperties.getPipProperties(properties)); + XACMLPdpServlet.queue.offer(req); + // + // We are now registered + // + finished = true; + registered=true; + } else if (connection.getResponseCode() >= 300 && connection.getResponseCode() <= 399) { + // + // Re-direction + // + String newLocation = connection.getHeaderField("Location"); + if (newLocation == null || newLocation.isEmpty()) { + logger.warn("Did not receive a valid re-direction location"); + finished = true; + } else { + logger.info("New Location: " + newLocation); + url = new URL(newLocation); + } + } else { + logger.warn("Failed: " + connection.getResponseCode() + " message: " + connection.getResponseMessage()); + finished = true; + } + } + } catch (Exception e) { + logger.error(e); + } finally { + // cleanup the connection + if (connection != null) { + try { + // For some reason trying to get the inputStream from the connection + // throws an exception rather than returning null when the InputStream does not exist. + InputStream is = null; + try { + is = connection.getInputStream(); + } catch (Exception e1) { + // ignore this + } + if (is != null) { + is.close(); + } + + } catch (IOException ex) { + logger.error("Failed to close connection: " + ex, ex); + } + connection.disconnect(); + } + } + // + // Wait a little while to try again + // + try { + if (registered == false) { + if (retries > 0) { + retries--; + } else if (retries == 0) { + break; + } + Thread.sleep(seconds * 1000); + } + } catch (InterruptedException e) { + interrupted = true; + this.terminate(); + } + } + synchronized(this) { + this.isRunning = false; + } + logger.info("Thread exiting...(registered=" + registered + ", interrupted=" + interrupted + ", isRunning=" + this.isRunning() + ", retries=" + retries + ")"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java new file mode 100755 index 0000000..f670579 --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java @@ -0,0 +1,690 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2013 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Properties; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.entity.ContentType; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.pap.PDPStatus.Status; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.std.pap.StdPDPStatus; +import com.att.research.xacml.util.XACMLProperties; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Servlet implementation class XacmlPdpServlet + * + * This is an implementation of the XACML 3.0 RESTful Interface with added features to support + * simple PAP RESTful API for policy publishing and PIP configuration changes. + * + * If you are running this the first time, then we recommend you look at the xacml.pdp.properties file. + * This properties file has all the default parameter settings. If you are running the servlet as is, + * then we recommend setting up you're container to run it on port 8080 with context "/pdp". Wherever + * the default working directory is set to, a "config" directory will be created that holds the policy + * and pip cache. This setting is located in the xacml.pdp.properties file. + * + * When you are ready to customize, you can create a separate xacml.pdp.properties on you're local file + * system and setup the parameters as you wish. Just set the Java VM System variable to point to that file: + * + * -Dxacml.properties=/opt/app/xacml/etc/xacml.pdp.properties + * + * Or if you only want to change one or two properties, simply set the Java VM System variable for that property. + * + * -Dxacml.rest.pdp.register=false + * + * @author pameladragosh + * + */ +@WebServlet( + description = "Implements the XACML PDP RESTful API and client PAP API.", + urlPatterns = { "/" }, + loadOnStartup=1, + initParams = { + @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pdp.properties", description = "The location of the PDP xacml.pdp.properties file holding configuration information.") + }) +public class XACMLPdpServlet extends HttpServlet implements Runnable { + private static final long serialVersionUID = 1L; + // + // Our application debug log + // + private static final Log logger = LogFactory.getLog(XACMLPdpServlet.class); + // + // This logger is specifically only for Xacml requests and their corresponding response. + // It's output ideally should be sent to a separate file from the application logger. + // + private static final Log requestLogger = LogFactory.getLog("xacml.request"); + // + // This thread may getting invoked on startup, to let the PAP know + // that we are up and running. + // + private Thread registerThread = null; + private XACMLPdpRegisterThread registerRunnable = null; + // + // This is our PDP engine pointer. There is a synchronized lock used + // for access to the pointer. In case we are servicing PEP requests while + // an update is occurring from the PAP. + // + private PDPEngine pdpEngine = null; + private static final Object pdpEngineLock = new Object(); + // + // This is our PDP's status. What policies are loaded (or not) and + // what PIP configurations are loaded (or not). + // There is a synchronized lock used for access to the object. + // + private static volatile StdPDPStatus status = new StdPDPStatus(); + private static final Object pdpStatusLock = new Object(); + // + // Queue of PUT requests + // + public static class PutRequest { + public Properties policyProperties = null; + public Properties pipConfigProperties = null; + + PutRequest(Properties policies, Properties pips) { + this.policyProperties = policies; + this.pipConfigProperties = pips; + } + } + public static volatile BlockingQueue<PutRequest> queue = new LinkedBlockingQueue<PutRequest>(2); + // + // This is our configuration thread that attempts to load + // a new configuration request. + // + private Thread configThread = null; + private volatile boolean configThreadTerminate = false; + + /** + * Default constructor. + */ + public XACMLPdpServlet() { + } + + /** + * @see Servlet#init(ServletConfig) + */ + public void init(ServletConfig config) throws ServletException { + // + // Initialize + // + XACMLRest.xacmlInit(config); + // + // Load our engine - this will use the latest configuration + // that was saved to disk and set our initial status object. + // + PDPEngine engine = XACMLPdpLoader.loadEngine(XACMLPdpServlet.status, null, null); + if (engine != null) { + synchronized(pdpEngineLock) { + pdpEngine = engine; + } + } + // + // Kick off our thread to register with the PAP servlet. + // + if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) { + this.registerRunnable = new XACMLPdpRegisterThread(); + this.registerThread = new Thread(this.registerRunnable); + this.registerThread.start(); + } + // + // This is our thread that manages incoming configuration + // changes. + // + this.configThread = new Thread(this); + this.configThread.start(); + } + + /** + * @see Servlet#destroy() + */ + public void destroy() { + super.destroy(); + logger.info("Destroying...."); + // + // Make sure the register thread is not running + // + if (this.registerRunnable != null) { + try { + this.registerRunnable.terminate(); + if (this.registerThread != null) { + this.registerThread.interrupt(); + this.registerThread.join(); + } + } catch (InterruptedException e) { + logger.error(e); + } + } + // + // Make sure the configure thread is not running + // + this.configThreadTerminate = true; + try { + this.configThread.interrupt(); + this.configThread.join(); + } catch (InterruptedException e) { + logger.error(e); + } + logger.info("Destroyed."); + } + + /** + * PUT - The PAP engine sends configuration information using HTTP PUT request. + * + * One parameter is expected: + * + * config=[policy|pip|all] + * + * policy - Expect a properties file that contains updated lists of the root and referenced policies that the PDP should + * be using for PEP requests. + * + * Specifically should AT LEAST contain the following properties: + * xacml.rootPolicies + * xacml.referencedPolicies + * + * In addition, any relevant information needed by the PDP to load or retrieve the policies to store in its cache. + * + * EXAMPLE: + * xacml.rootPolicies=PolicyA.1, PolicyB.1 + * + * PolicyA.1.url=http://localhost:9090/PAP?id=b2d7b86d-d8f1-4adf-ba9d-b68b2a90bee1&version=1 + * PolicyB.1.url=http://localhost:9090/PAP/id=be962404-27f6-41d8-9521-5acb7f0238be&version=1 + * + * xacml.referencedPolicies=RefPolicyC.1, RefPolicyD.1 + * + * RefPolicyC.1.url=http://localhost:9090/PAP?id=foobar&version=1 + * RefPolicyD.1.url=http://localhost:9090/PAP/id=example&version=1 + * + * pip - Expect a properties file that contain PIP engine configuration properties. + * + * Specifically should AT LEAST the following property: + * xacml.pip.engines + * + * In addition, any relevant information needed by the PDP to load and configure the PIPs. + * + * EXAMPLE: + * xacml.pip.engines=foo,bar + * + * foo.classname=com.foo + * foo.sample=abc + * foo.example=xyz + * ...... + * + * bar.classname=com.bar + * ...... + * + * all - Expect ALL new configuration properties for the PDP + * + * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // + // Dump our request out + // + if (logger.isDebugEnabled()) { + XACMLRest.dumpRequest(request); + } + // + // What is being PUT? + // + String cache = request.getParameter("cache"); + // + // Should be a list of policy and pip configurations in Java properties format + // + if (cache != null && request.getContentType().equals("text/x-java-properties")) { + if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) { + String message = "Content-Length larger than server will accept."; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + this.doPutConfig(cache, request, response); + } else { + String message = "Invalid cache: '" + cache + "' or content-type: '" + request.getContentType() + "'"; + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + } + + protected void doPutConfig(String config, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + // prevent multiple configuration changes from stacking up + if (XACMLPdpServlet.queue.remainingCapacity() <= 0) { + logger.error("Queue capacity reached"); + response.sendError(HttpServletResponse.SC_CONFLICT, "Multiple configuration changes waiting processing."); + return; + } + // + // Read the properties data into an object. + // + Properties newProperties = new Properties(); + newProperties.load(request.getInputStream()); + // should have something in the request + if (newProperties.size() == 0) { + logger.error("No properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT must contain at least one property"); + return; + } + // + // Which set of properties are they sending us? Whatever they send gets + // put on the queue (if there is room). + // + if (config.equals("policies")) { + newProperties = XACMLProperties.getPolicyProperties(newProperties, true); + if (newProperties.size() == 0) { + logger.error("No policy properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=policies must contain at least one policy property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(newProperties, null)); + } else if (config.equals("pips")) { + newProperties = XACMLProperties.getPipProperties(newProperties); + if (newProperties.size() == 0) { + logger.error("No pips properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=pips must contain at least one pip property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(null, newProperties)); + } else if (config.equals("all")) { + Properties newPolicyProperties = XACMLProperties.getPolicyProperties(newProperties, true); + if (newPolicyProperties.size() == 0) { + logger.error("No policy properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one policy property"); + return; + } + Properties newPipProperties = XACMLProperties.getPipProperties(newProperties); + if (newPipProperties.size() == 0) { + logger.error("No pips properties in PUT"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "PUT with cache=all must contain at least one pip property"); + return; + } + XACMLPdpServlet.queue.offer(new PutRequest(newPolicyProperties, newPipProperties)); + } else { + // + // Invalid value + // + logger.error("Invalid config value: " + config); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Config must be one of 'policies', 'pips', 'all'"); + return; + } + } catch (Exception e) { + logger.error("Failed to process new configuration.", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + /** + * Parameters: type=hb|config|Status + * + * 1. HeartBeat Status + * HeartBeat + * OK - All Policies are Loaded, All PIPs are Loaded + * LOADING_IN_PROGRESS - Currently loading a new policy set/pip configuration + * LAST_UPDATE_FAILED - Need to track the items that failed during last update + * LOAD_FAILURE - ??? Need to determine what information is sent and how + * 2. Configuration + * 3. Status + * return the StdPDPStatus object in the Response content + * + * + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + XACMLRest.dumpRequest(request); + // + // What are they requesting? + // + boolean returnHB = false; + response.setHeader("Cache-Control", "no-cache"); + String type = request.getParameter("type"); + // type might be null, so use equals on string constants + if ("config".equals(type)) { + response.setContentType("text/x-java-properties"); + try { + String lists = XACMLProperties.PROP_ROOTPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_ROOTPOLICIES, ""); + lists = lists + "\n" + XACMLProperties.PROP_REFERENCEDPOLICIES + "=" + XACMLProperties.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, "") + "\n"; + try (InputStream listInputStream = new ByteArrayInputStream(lists.getBytes()); + InputStream pipInputStream = Files.newInputStream(XACMLPdpLoader.getPIPConfig()); + OutputStream os = response.getOutputStream()) { + IOUtils.copy(listInputStream, os); + IOUtils.copy(pipInputStream, os); + } + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception e) { + logger.error("Failed to copy property file", e); + response.sendError(400, "Failed to copy Property file"); + } + + } else if ("hb".equals(type)) { + returnHB = true; + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + + } else if ("Status".equals(type)) { + // convert response object to JSON and include in the response + synchronized(pdpStatusLock) { + ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), status); + } + response.setStatus(HttpServletResponse.SC_OK); + + } else { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "type not 'config' or 'hb'"); + } + if (returnHB) { + synchronized(pdpStatusLock) { + response.addHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB, status.getStatus().toString()); + } + } + } + + /** + * POST - We expect XACML requests to be posted by PEP applications. They can be in the form of XML or JSON according + * to the XACML 3.0 Specifications for both. + * + * + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // + // no point in doing any work if we know from the get-go that we cannot do anything with the request + // + if (status.getLoadedRootPolicies().size() == 0) { + logger.warn("Request from PEP at " + request.getRequestURI() + " for service when PDP has No Root Policies loaded"); + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + return; + } + + XACMLRest.dumpRequest(request); + // + // Set our no-cache header + // + response.setHeader("Cache-Control", "no-cache"); + // + // They must send a Content-Type + // + if (request.getContentType() == null) { + logger.warn("Must specify a Content-Type"); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "no content-type given"); + return; + } + // + // Limit the Content-Length to something reasonable + // + if (request.getContentLength() > Integer.parseInt(XACMLProperties.getProperty("MAX_CONTENT_LENGTH", "32767"))) { + String message = "Content-Length larger than server will accept."; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + if (request.getContentLength() <= 0) { + String message = "Content-Length is negative"; + logger.info(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + ContentType contentType = null; + try { + contentType = ContentType.parse(request.getContentType()); + } + catch (Exception e) { + String message = "Parsing Content-Type: " + request.getContentType() + ", error=" + e.getMessage(); + logger.error(message, e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // What exactly did they send us? + // + String incomingRequestString = null; + Request pdpRequest = null; + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) { + // + // Read in the string + // + StringBuilder buffer = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + String line; + while((line = reader.readLine()) != null){ + buffer.append(line); + } + incomingRequestString = buffer.toString(); + logger.info(incomingRequestString); + // + // Parse into a request + // + try { + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + pdpRequest = JSONRequest.load(incomingRequestString); + } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) { + pdpRequest = DOMRequest.load(incomingRequestString); + } + } + catch(Exception e) { + logger.error("Could not parse request", e); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + return; + } + } else { + String message = "unsupported content type" + request.getContentType(); + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // Did we successfully get and parse a request? + // + if (pdpRequest == null || pdpRequest.getRequestAttributes() == null || pdpRequest.getRequestAttributes().size() <= 0) { + String message = "Zero Attributes found in the request"; + logger.error(message); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); + return; + } + // + // Run it + // + try { + // + // Get the pointer to the PDP Engine + // + PDPEngine myEngine = null; + synchronized(pdpEngineLock) { + myEngine = this.pdpEngine; + } + if (myEngine == null) { + String message = "No engine loaded."; + logger.error(message); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + // + // Send the request and save the response + // + long lTimeStart, lTimeEnd; + Response pdpResponse = null; + +//TODO - Make this unnecessary +//TODO It seems that the PDP Engine is not thread-safe, so when a configuration change occurs in the middle of processing +//TODO a PEP Request, that Request fails (it throws a NullPointerException in the decide() method). +//TODO Using synchronize will slow down processing of PEP requests, possibly by a significant amount. +//TODO Since configuration changes are rare, it would be A Very Good Thing if we could eliminate this sychronized block. +//TODO +//TODO This problem was found by starting one PDP then +//TODO RestLoadTest switching between 2 configurations, 1 second apart +//TODO both configurations contain the datarouter policy +//TODO both configurations already have all policies cached in the PDPs config directory +//TODO RestLoadTest started with the Datarouter test requests, 5 threads, no interval +//TODO With that configuration this code (without the synchronized) throws a NullPointerException +//TODO within a few seconds. +// +synchronized(pdpEngineLock) { + myEngine = this.pdpEngine; + try { + lTimeStart = System.currentTimeMillis(); + pdpResponse = myEngine.decide(pdpRequest); + lTimeEnd = System.currentTimeMillis(); + } catch (PDPException e) { + String message = "Exception during decide: " + e.getMessage(); + logger.error(message); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } +} + requestLogger.info(lTimeStart + "=" + incomingRequestString); + if (logger.isDebugEnabled()) { + logger.debug("Request time: " + (lTimeEnd - lTimeStart) + "ms"); + } + // + // Convert Response to appropriate Content-Type + // + if (pdpResponse == null) { + requestLogger.info(lTimeStart + "=" + "{}"); + throw new Exception("Failed to get response from PDP engine."); + } + // + // Set our content-type + // + response.setContentType(contentType.getMimeType()); + // + // Convert the PDP response object to a String to + // return to our caller as well as dump to our loggers. + // + String outgoingResponseString = ""; + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + // + // Get it as a String. This is not very efficient but we need to log our + // results for auditing. + // + outgoingResponseString = JSONResponse.toString(pdpResponse, logger.isDebugEnabled()); + if (logger.isDebugEnabled()) { + logger.debug(outgoingResponseString); + // + // Get rid of whitespace + // + outgoingResponseString = JSONResponse.toString(pdpResponse, false); + } + } else if ( contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) { + // + // Get it as a String. This is not very efficient but we need to log our + // results for auditing. + // + outgoingResponseString = DOMResponse.toString(pdpResponse, logger.isDebugEnabled()); + if (logger.isDebugEnabled()) { + logger.debug(outgoingResponseString); + // + // Get rid of whitespace + // + outgoingResponseString = DOMResponse.toString(pdpResponse, false); + } + } + // + // lTimeStart is used as an ID within the requestLogger to match up + // request's with responses. + // + requestLogger.info(lTimeStart + "=" + outgoingResponseString); + response.getWriter().print(outgoingResponseString); + } + catch (Exception e) { + String message = "Exception executing request: " + e; + logger.error(message, e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + response.setStatus(HttpServletResponse.SC_OK); + } + + @Override + public void run() { + // + // Keep running until we are told to terminate + // + try { + while (! this.configThreadTerminate) { + PutRequest request = XACMLPdpServlet.queue.take(); + StdPDPStatus newStatus = new StdPDPStatus(); + +//TODO - This is related to the problem discussed in the doPost() method about the PDPEngine not being thread-safe. +//TODO See that discussion, and when the PDPEngine is made thread-safe it should be ok to move the loadEngine out of +//TODO the synchronized block. +//TODO However, since configuration changes should be rare we may not care about changing this. +PDPEngine newEngine = null; + synchronized(pdpStatusLock) { + XACMLPdpServlet.status.setStatus(Status.UPDATING_CONFIGURATION); +newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties); + } +// PDPEngine newEngine = XACMLPdpLoader.loadEngine(newStatus, request.policyProperties, request.pipConfigProperties); + if (newEngine != null) { + synchronized(XACMLPdpServlet.pdpEngineLock) { + this.pdpEngine = newEngine; + try { + logger.info("Saving configuration."); + if (request.policyProperties != null) { + try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPDPPolicyCache())) { + request.policyProperties.store(os, ""); + } + } + if (request.pipConfigProperties != null) { + try (OutputStream os = Files.newOutputStream(XACMLPdpLoader.getPIPConfig())) { + request.pipConfigProperties.store(os, ""); + } + } + newStatus.setStatus(Status.UP_TO_DATE); + + } catch (Exception e) { + logger.error("Failed to store new properties."); + newStatus.setStatus(Status.LOAD_ERRORS); + newStatus.addLoadWarning("Unable to save configuration: " + e.getMessage()); + } + } + } else { + newStatus.setStatus(Status.LAST_UPDATE_FAILED); + } + synchronized(pdpStatusLock) { + XACMLPdpServlet.status.set(newStatus); + } + } + } catch (InterruptedException e) { + logger.error("interrupted"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java new file mode 100755 index 0000000..550d1b2 --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java @@ -0,0 +1,75 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest.impl; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPFinderFactory; +import com.att.research.xacml.std.pip.finders.ConfigurableEngineFinder; +import com.att.research.xacml.util.XACMLProperties; + +public class XACMLPdpPIPFinderFactory extends PIPFinderFactory { + private ConfigurableEngineFinder pipFinder; + + private static Log logger = LogFactory.getLog(XACMLPdpPIPFinderFactory.class); + + public XACMLPdpPIPFinderFactory() { + } + + public XACMLPdpPIPFinderFactory(Properties properties) { + } + + @Override + public PIPFinder getFinder() throws PIPException { + if (pipFinder == null) { + synchronized(this) { + if (pipFinder == null) { + if (logger.isDebugEnabled()) { + logger.debug("Creating default configurable engine finder"); + } + pipFinder = new ConfigurableEngineFinder(); + Properties xacmlProperties = null; + try { + xacmlProperties = XACMLProperties.getProperties(); + } catch (Exception ex) { + logger.error("Exception getting XACML properties: " + ex.getMessage(), ex); + return null; + } + if (xacmlProperties != null) { + ((ConfigurableEngineFinder)pipFinder).configure(xacmlProperties); + } + } + } + } + return pipFinder; + } + + @Override + public PIPFinder getFinder(Properties properties) throws PIPException { + if (pipFinder == null) { + synchronized(this) { + if (pipFinder == null) { + if (logger.isDebugEnabled()) { + logger.debug("Creating configurable engine finder using: " + properties); + } + pipFinder = new ConfigurableEngineFinder(); + ((ConfigurableEngineFinder)pipFinder).configure(properties); + } + } + } + return this.pipFinder; + } +} http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java new file mode 100755 index 0000000..421839a --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java @@ -0,0 +1,197 @@ +/* + * AT&T - PROPRIETARY + * THIS FILE CONTAINS PROPRIETARY INFORMATION OF + * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN + * ACCORDANCE WITH APPLICABLE AGREEMENTS. + * + * Copyright (c) 2014 AT&T Knowledge Ventures + * Unpublished and Not for Publication + * All Rights Reserved + */ +package com.att.research.xacml.rest.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.policy.Policy; +import com.att.research.xacmlatt.pdp.policy.PolicyDef; +import com.att.research.xacmlatt.pdp.policy.PolicyFinder; +import com.att.research.xacmlatt.pdp.policy.PolicyFinderFactory; +import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinder; +import com.google.common.base.Splitter; + +public class XACMLPdpPolicyFinderFactory extends PolicyFinderFactory { + public static final String PROP_FILE = ".file"; + public static final String PROP_URL = ".url"; + + private static Log logger = LogFactory.getLog(XACMLPdpPolicyFinderFactory.class); + private List<PolicyDef> rootPolicies; + private List<PolicyDef> referencedPolicies; + private boolean needsInit = true; + + private Properties properties = null; + + public XACMLPdpPolicyFinderFactory() { + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + public XACMLPdpPolicyFinderFactory(Properties properties) { + // + // Save our properties + // + this.properties = properties; + // + // Here we differ from the StdPolicyFinderFactory in that we initialize right away. + // We do not wait for a policy request to happen to look for and load policies. + // + this.init(); + } + + /** + * Loads the <code>PolicyDef</code> for the given <code>String</code> identifier by looking first + * for a ".file" property associated with the ID and using that to load from a <code>File</code> and + * looking for a ".url" property associated with the ID and using that to load from a <code>URL</code>. + * + * @param policyId the <code>String</code> identifier for the policy + * @return a <code>PolicyDef</code> loaded from the given identifier + */ + protected PolicyDef loadPolicyDef(String policyId) { + String propLocation = null; + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_FILE); + } else { + propLocation = this.properties.getProperty(policyId + PROP_FILE); + } + if (propLocation != null) { + File fileLocation = new File(propLocation); + if (!fileLocation.exists()) { + XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " does not exist."); + } else if (!fileLocation.canRead()) { + XACMLPdpPolicyFinderFactory.logger.error("Policy file " + fileLocation.getAbsolutePath() + " cannot be read."); + } else { + try { + XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + fileLocation); + PolicyDef policyDef = DOMPolicyDef.load(fileLocation); + if (policyDef != null) { + return policyDef; + } + } catch (DOMStructureException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Error loading policy file " + fileLocation.getAbsolutePath() + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } + } + } + if (this.properties == null) { + propLocation = XACMLProperties.getProperty(policyId + PROP_URL); + } else { + propLocation = this.properties.getProperty(policyId + PROP_URL); + } + if (propLocation != null) { + InputStream is = null; + try { + URL url = new URL(propLocation); + URLConnection urlConnection = url.openConnection(); + XACMLPdpPolicyFinderFactory.logger.info("Loading policy file " + url.toString()); + is = urlConnection.getInputStream(); + PolicyDef policyDef = DOMPolicyDef.load(is); + if (policyDef != null) { + return policyDef; + } + } catch (MalformedURLException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Invalid URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (IOException ex) { + XACMLPdpPolicyFinderFactory.logger.error("IOException opening URL " + propLocation + ": " + ex.getMessage(), ex); + } catch (DOMStructureException ex) { + XACMLPdpPolicyFinderFactory.logger.error("Invalid Policy " + propLocation + ": " + ex.getMessage(), ex); + return new Policy(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, ex.getMessage()); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + XACMLPdpPolicyFinderFactory.logger.error("Exception closing InputStream for GET of url " + propLocation + " : " + e.getMessage() + " (May be memory leak)", e); + } + } + } + } + + XACMLPdpPolicyFinderFactory.logger.error("No known location for Policy " + policyId); + return null; + } + + /** + * Finds the identifiers for all of the policies referenced by the given property name in the + * <code>XACMLProperties</code> and loads them using the requested loading method. + * + * @param propertyName the <code>String</code> name of the property containing the list of policy identifiers + * @return a <code>List</code> of <code>PolicyDef</code>s loaded from the given property name + */ + protected List<PolicyDef> getPolicyDefs(String propertyName) { + String policyIds = XACMLProperties.getProperty(propertyName); + if (policyIds == null || policyIds.length() == 0) { + return null; + } + + Iterable<String> policyIdArray = Splitter.on(',').trimResults().omitEmptyStrings().split(policyIds); + if (policyIdArray == null) { + return null; + } + + List<PolicyDef> listPolicyDefs = new ArrayList<PolicyDef>(); + for (String policyId : policyIdArray) { + PolicyDef policyDef = this.loadPolicyDef(policyId); + if (policyDef != null) { + listPolicyDefs.add(policyDef); + } + } + return listPolicyDefs; + } + + protected synchronized void init() { + if (this.needsInit) { + if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) { + XACMLPdpPolicyFinderFactory.logger.debug("Initializing"); + } + this.rootPolicies = this.getPolicyDefs(XACMLProperties.PROP_ROOTPOLICIES); + this.referencedPolicies = this.getPolicyDefs(XACMLProperties.PROP_REFERENCEDPOLICIES); + if (XACMLPdpPolicyFinderFactory.logger.isDebugEnabled()) { + XACMLPdpPolicyFinderFactory.logger.debug("Root Policies: " + this.rootPolicies); + XACMLPdpPolicyFinderFactory.logger.debug("Referenced Policies: " + this.referencedPolicies); + } + this.needsInit = false; + } + } + + @Override + public PolicyFinder getPolicyFinder() throws FactoryException { + // + // Force using any properties that were passed upon construction + // + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, this.properties); + } + + @Override + public PolicyFinder getPolicyFinder(Properties properties) throws FactoryException { + return new StdPolicyFinder(this.rootPolicies, this.referencedPolicies, properties); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/src/main/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/src/main/resources/log4j.properties b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties new file mode 100755 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pdp-rest/src/main/resources/log4j.properties @@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class new file mode 100644 index 0000000..43eeb50 Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpLoader.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class new file mode 100644 index 0000000..b43d395 Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpRegisterThread.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class new file mode 100644 index 0000000..9809046 Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class new file mode 100644 index 0000000..59e6daa Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/XACMLPdpServlet.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class new file mode 100644 index 0000000..54de986 Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class new file mode 100644 index 0000000..f9825d8 Binary files /dev/null and b/openaz-xacml-pdp-rest/target/classes/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/classes/log4j.properties ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/classes/log4j.properties b/openaz-xacml-pdp-rest/target/classes/log4j.properties new file mode 100644 index 0000000..b45fa2f --- /dev/null +++ b/openaz-xacml-pdp-rest/target/classes/log4j.properties @@ -0,0 +1,22 @@ +# +# Use this properties for debugging and development. +# +# +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, MAIN_LOG + +# A1 is set to be a ConsoleAppender. +log4j.appender.MAIN_LOG=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.MAIN_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.MAIN_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} [%t] %-5p %l- %m%n + +# +# This is specifically for Xacml request/response logging +# +log4j.logger.xacml.request=INFO, REQUEST_LOG + +log4j.appender.REQUEST_LOG=org.apache.log4j.ConsoleAppender +log4j.appender.REQUEST_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.REQUEST_LOG.layout.ConversionPattern=%d{yyyy_MM_dd_HH_mm_ss_SSS} %m%n \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties new file mode 100644 index 0000000..5eebb03 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Tue Apr 07 07:42:37 EDT 2015 +version=0.0.1-SNAPSHOT +groupId=org.openliberty.openaz +artifactId=openaz-xacml-pdp-rest http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..667efe3 --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,6 @@ +com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.class +com/att/research/xacml/rest/XACMLPdpServlet$PutRequest.class +com/att/research/xacml/rest/XACMLPdpServlet.class +com/att/research/xacml/rest/XACMLPdpLoader.class +com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.class +com/att/research/xacml/rest/XACMLPdpRegisterThread.class http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..12a596f --- /dev/null +++ b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,5 @@ +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpLoader.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPolicyFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpServlet.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/impl/XACMLPdpPIPFinderFactory.java +/Users/ajith/IdeaProjects/openaz/openaz-xacml-pdp-rest/src/main/java/com/att/research/xacml/rest/XACMLPdpRegisterThread.java http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/openaz-xacml-pdp-rest/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000..8eca8bd Binary files /dev/null and b/openaz-xacml-pdp-rest/target/openaz-xacml-pdp-rest-0.0.1-SNAPSHOT.jar differ http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp-rest/xacml.pdp.properties ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp-rest/xacml.pdp.properties b/openaz-xacml-pdp-rest/xacml.pdp.properties new file mode 100755 index 0000000..34e6b77 --- /dev/null +++ b/openaz-xacml-pdp-rest/xacml.pdp.properties @@ -0,0 +1,53 @@ +# Default XACML Properties File for PDP RESTful servlet +# +# Standard API Factories +# +xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory +xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory +xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory +# NOT USED SEE BELOW xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory +xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory +# +# AT&T PDP Implementation Factories +# +xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory +xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory +xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory +# NOT USED SEE BELOW xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory + +# +# AT&T RESTful PDP Implementation Factories +# +xacml.pipFinderFactory=com.att.research.xacml.rest.impl.XACMLPdpPIPFinderFactory +xacml.att.policyFinderFactory=com.att.research.xacml.rest.XACMLPdpPolicyFinderFactory +# +# PDP RESTful API properties +# +# Set this to the address where the XACML-PAP-REST servlet is running +# +xacml.rest.pap.url=http://localhost:9090/pap/ +# +# Give the running PDP an ID for the PAP. The url that its running as is a good choice. +# The PAP identifies PDP's using the URL of the PDP. +# +xacml.rest.pdp.id=http://localhost:8080/pdp/ +# +# Set the directory where the PDP holds its Policy Cache and PIP Configuration +# +xacml.rest.pdp.config=config +# +# Initialize register with PAP servlet +# +xacml.rest.pdp.register=true +# +# Sleep period in seconds between register attempts +# +xacml.rest.pdp.register.sleep=15 +# +# number of attempts to register. -1 means keep trying forever. +# +xacml.rest.pdp.register.retries=-1 +# +# max number of bytes in a POST of a XML/JSON request +# +xacml.rest.pdp.maxcontent=32767 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/logging.properties ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp/logging.properties b/openaz-xacml-pdp/logging.properties new file mode 100755 index 0000000..ef56def --- /dev/null +++ b/openaz-xacml-pdp/logging.properties @@ -0,0 +1,9 @@ +handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler + +.level = ALL + +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.FileHandler.level = INFO +java.util.logging.FileHandler.pattern=%h/xacml_log%u.log +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-pdp/pom.xml ---------------------------------------------------------------------- diff --git a/openaz-xacml-pdp/pom.xml b/openaz-xacml-pdp/pom.xml new file mode 100755 index 0000000..e55bdf4 --- /dev/null +++ b/openaz-xacml-pdp/pom.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>openaz</artifactId> + <groupId>org.openliberty.openaz</groupId> + <version>0.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>openaz-xacml-pdp</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openaz-xacml</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file
