You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openaz.apache.org by pd...@apache.org on 2015/04/13 17:38:10 UTC

[10/51] [partial] incubator-openaz git commit: Initial seed of merged of AT&T and JP Morgan code

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
new file mode 100755
index 0000000..be0b46f
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTest.java
@@ -0,0 +1,95 @@
+/*
+ *                        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.xacmlatt.pdp.test.conformance;
+
+import java.io.File;
+
+/**
+ * ConformanceTest represents a collection of XACML files with a root Policy document, optional referenced Policy documents, a Request, and a Response.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class ConformanceTest {
+	private String testName;
+	private File request;
+	private File response;
+	private ConformanceRepository repository;
+	
+	public ConformanceTest(String name, ConformanceRepository conformanceRepository, File fileRequest, File fileResponse) {
+		this.testName	= name;
+		this.request	= fileRequest;
+		this.response	= fileResponse;
+		this.repository	= conformanceRepository;
+	}
+	
+	public ConformanceTest(String name) {
+		this.testName	= name;
+	}
+	
+	public String getTestName() {
+		return this.testName;
+	}
+	public void setTestName(String s) {
+		this.testName	= s;
+	}
+	public ConformanceRepository getRepository() {
+		if (this.repository == null) {
+			this.repository	= new ConformanceRepository();
+		}
+		return this.repository;
+	}
+	public File getRequest() {
+		return this.request;
+	}
+	public void setRequest(File f) {
+		this.request	= f;
+	}
+	public File getResponse() {
+		return this.response;
+	}
+	public void setResponse(File f) {
+		this.response	= f;
+	}
+	
+	public boolean isComplete() {
+		return this.getTestName() != null && this.getRepository() != null && this.getRepository().hasRootPolicy() && this.getRequest() != null && this.getResponse() != null;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder	= new StringBuilder();
+		boolean needColon			= false;
+		if (this.getTestName() != null) {
+			stringBuilder.append(this.getTestName());
+			needColon	= true;
+		}
+		if (this.getRepository() != null) {
+			
+		}
+		if (this.getRequest() != null) {
+			if (needColon) {
+				stringBuilder.append(':');
+			}
+			stringBuilder.append(this.getRequest().getName());
+			needColon	= true;
+		}
+		if (this.getResponse() != null) {
+			if (needColon) {
+				stringBuilder.append(':');
+			}
+			stringBuilder.append(this.getResponse().getName());
+			needColon	= true;
+		}
+		return stringBuilder.toString();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.java
new file mode 100755
index 0000000..822006a
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestEngine.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) 2013 AT&T Knowledge Ventures
+ *              Unpublished and Not for Publication
+ *                     All Rights Reserved
+ */
+package com.att.research.xacmlatt.pdp.test.conformance;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.api.pdp.ScopeResolver;
+import com.att.research.xacml.std.dom.DOMProperties;
+import com.att.research.xacml.std.dom.DOMRequest;
+import com.att.research.xacml.std.dom.DOMResponse;
+import com.att.research.xacml.util.FactoryException;
+
+/**
+ * ConformanceTestEngine handles the creation of the PDPEngine for a ConformanceTest instance.
+ * 
+ * @author car
+ * @version $Revision: 1.2 $
+ */
+public class ConformanceTestEngine {
+	private Log logger	= LogFactory.getLog(ConformanceTestEngine.class);
+	
+	private PDPEngineFactory pdpEngineFactory;
+	private ScopeResolver scopeResolver;
+	private boolean lenientRequests;
+	private boolean lenientPolicies;
+	private int iterations			= 1;
+	
+	// total of all first calls to decide()
+	private long firstDecideTime;
+	private int numberOfFirstDecides = 0;
+	
+	// total of all non-first-calls to decide()
+	private long decideTimeMultiple;
+	
+	// total of average time each test case uses for a Request
+	// (sum of : for each test case, average of all non-first-call calls to decide() )
+	private long avgDecideTimeMultiple = 0;
+	
+	protected PDPEngineFactory getPDPEngineFactory() throws FactoryException {
+		if (this.pdpEngineFactory == null) {
+			this.pdpEngineFactory	= PDPEngineFactory.newInstance();
+			this.pdpEngineFactory.setScopeResolver(this.scopeResolver);
+		}
+		return this.pdpEngineFactory;
+	}
+	
+	public ConformanceTestEngine(ScopeResolver scopeResolverIn, boolean lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn) {
+		this.scopeResolver		= scopeResolverIn;
+		this.lenientRequests	= lenientRequestsIn;
+		this.lenientPolicies	= lenientPoliciesIn;
+		this.iterations			= iterationsIn;
+	}
+	
+	public ConformanceTestResult run(ConformanceTest conformanceTest) {
+		if (conformanceTest.getRequest() == null || conformanceTest.getResponse() == null || conformanceTest.getRepository() == null) {
+			logger.error("Incomplete Conformance Test: " + conformanceTest.getTestName());
+		}
+		PDPEngineFactory thisPDPEngineFactory	= null;
+		try {
+			thisPDPEngineFactory	= this.getPDPEngineFactory();
+		} catch (FactoryException ex) {
+			return new ConformanceTestResult(conformanceTest, ex);
+		}
+		
+		ConformanceTestResult conformanceTestResult	= new ConformanceTestResult(conformanceTest, iterations);
+		
+		/*
+		 * Load the request
+		 */
+		Request request			= null;
+		boolean isLenient		= DOMProperties.isLenient();
+		try {
+			DOMProperties.setLenient(this.lenientRequests);
+			try {
+				request		= DOMRequest.load(conformanceTest.getRequest());
+				conformanceTestResult.setRequest(request);
+			} catch (Exception ex) {
+				logger.error("Exception loading Request file " + conformanceTest.getRequest().getAbsolutePath(), ex);
+				conformanceTestResult.setError(ex);
+				return conformanceTestResult;
+				
+			}
+			
+			/*
+			 * Load the expected response
+			 */
+			Response response		= null;
+			try {
+				response	= DOMResponse.load(conformanceTest.getResponse());
+				conformanceTestResult.setExpectedResponse(response);
+			} catch (Exception ex) {
+				logger.error("Exception loading Response file " + conformanceTest.getResponse().getAbsolutePath(), ex);
+				conformanceTestResult.setError(ex);
+				return conformanceTestResult;
+			}
+			
+			/*
+			 * Set up the configuration for the policy finder
+			 */
+			conformanceTest.getRepository().setXACMLProperties();
+			DOMProperties.setLenient(this.lenientPolicies);
+			
+			/*
+			 * Create the engine
+			 */
+			PDPEngine pdpEngine		= null;
+			try {
+				// pdpEngine	= thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(), conformanceTest.getReferencedPolicies(), pipFinderEngine);
+				pdpEngine		= thisPDPEngineFactory.newEngine();
+			} catch (Exception ex) {
+				logger.error("Exception getting PDP engine instance", ex);
+				conformanceTestResult.setError(ex);
+				return conformanceTestResult;
+			}
+			if (pdpEngine == null) {
+				logger.error("Null PDP engine");
+				conformanceTestResult.setError(new NullPointerException("Null engine"));
+				return conformanceTestResult;
+			}
+			
+			/*
+			 * Run the request
+			 */
+			long startTime, endTime;
+			long curDecideTime	= this.firstDecideTime;
+			try {
+				startTime	= System.nanoTime();
+				response	= pdpEngine.decide(request);
+				endTime = System.nanoTime();
+//System.out.println(endTime  - startTime);
+				// add to total
+				this.firstDecideTime	+= endTime - startTime;
+				this.numberOfFirstDecides++;
+				// remember just this test
+				conformanceTestResult.setFirstCallTime(endTime - startTime);
+				conformanceTestResult.setActualResponse(response);
+			} catch (Exception ex) {
+				logger.error("Exception in decide", ex);
+				conformanceTestResult.setError(ex);
+				return conformanceTestResult;
+			}
+			if (response == null) {
+				logger.error("Null Response");
+				conformanceTestResult.setError(new NullPointerException("Null Response"));
+				return conformanceTestResult;			
+			}
+			
+			long localLoopTime = 0;
+			try {
+				// if user requested non-first-call calls to decide() to get performance info, run them now.
+				// We can ignore the result since we are only interested in how long they take to process the Request.
+				for (int i = 0 ; i < this.iterations ; i++) {
+					startTime	= System.nanoTime();
+					pdpEngine.decide(request);
+					endTime = System.nanoTime();
+//System.out.println(endTime - startTime);					
+					// add to the global total for all tests
+					this.decideTimeMultiple	+= (endTime - startTime);
+					// remember just this one test's info
+					localLoopTime += (endTime - startTime);
+				}
+			} catch (Exception ex) {
+				logger.error("Exception in iterated decide", ex);
+				return conformanceTestResult;
+			}
+
+			// add to total average for non-first-call times for all test cases
+			avgDecideTimeMultiple += (localLoopTime / iterations);
+//System.out.println("localLoop="+localLoopTime + "   it="+iterations + "   avg=" + (localLoopTime / iterations) );
+			// remember average time for just this test
+			conformanceTestResult.setAverageTotalLoopTime(localLoopTime/iterations);
+			
+			long elapsedDecideTime	= this.firstDecideTime - curDecideTime;
+			logger.info("Decide Time: " + elapsedDecideTime + "ns");
+			
+			return conformanceTestResult;
+		} finally {
+			DOMProperties.setLenient(isLenient);
+		}
+	}
+
+	public long getFirstDecideTime() {
+		return this.firstDecideTime;
+	}
+	
+	public long getDecideTimeMultiple() {
+		return this.decideTimeMultiple;
+	}
+	
+	
+	public long getAvgFirstDecideTime() {
+		return this.firstDecideTime / numberOfFirstDecides;
+	}
+	public long getAvgDecideTimeMultiple() {
+		return this.avgDecideTimeMultiple / numberOfFirstDecides;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
new file mode 100755
index 0000000..9c895c6
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestResult.java
@@ -0,0 +1,113 @@
+/*
+ *                        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.xacmlatt.pdp.test.conformance;
+
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.Response;
+
+/**
+ * ConformanceTestResult holds all of the objects for a single conformance test run.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ConformanceTestResult {
+	private ConformanceTest		conformanceTest;
+	private Request				request;
+	private Response			expectedResponse;
+	private Response			actualResponse;
+	private ResponseMatchResult	responseMatchResult;
+	private Exception			error;
+	
+	// performance timings
+	private long 			firstCallTime;
+	private long 			averageTotalLoopTime;
+	
+	// how many non-first-call times the decide() was called
+	private int iterations;
+	
+	public ConformanceTestResult(ConformanceTest conformanceTestIn, int iterations) {
+		this.conformanceTest	= conformanceTestIn;
+		this.iterations = iterations;
+	}
+	
+	public ConformanceTestResult(ConformanceTest conformanceTestIn, Exception errorIn) {
+		this.conformanceTest	= conformanceTestIn;
+		this.error				= errorIn;
+	}
+	
+	public int getIterations() {
+		return this.iterations;
+	}
+
+	public ConformanceTest getConformanceTest() {
+		return this.conformanceTest;
+	}
+	public void setConformanceTest(ConformanceTest conformanceTestIn) {
+		this.conformanceTest	= conformanceTestIn;
+	}
+	
+	public Request getRequest() {
+		return this.request;
+	}
+	public void setRequest(Request requestIn) {
+		this.request	= requestIn;
+	}
+	
+	public Response getExpectedResponse() {
+		return this.expectedResponse;
+	}
+	public void setExpectedResponse(Response response) {
+		this.expectedResponse		= response;
+		this.responseMatchResult	= null;
+	}
+	
+	public Response getActualResponse() {
+		return this.actualResponse;
+	}
+	public void setActualResponse(Response response) {
+		this.actualResponse		= response;
+		this.responseMatchResult	= null;
+	}
+	
+	public ResponseMatchResult getResponseMatchResult() {
+		if (this.responseMatchResult == null && (this.actualResponse != null && this.expectedResponse != null)) {
+			this.computeResponseMatchResult();
+		}
+		return this.responseMatchResult;
+	}
+	public void computeResponseMatchResult() {
+		if (this.expectedResponse != null && this.actualResponse != null) {
+			this.responseMatchResult	= ResponseMatchResult.newInstance(this.expectedResponse, this.actualResponse);
+		}
+	}
+	public Exception getError() {
+		return this.error;
+	}
+	public void setError(Exception ex) {
+		this.error	= ex;
+	}
+	
+	public long getFirstCallTime() {
+		return firstCallTime;
+	}
+	public void setFirstCallTime(long t) {
+		firstCallTime = t;
+	}
+	public long getAverageTotalLoopTime(){
+		return averageTotalLoopTime;
+	}
+	public void setAverageTotalLoopTime(long t) {
+		averageTotalLoopTime = t;
+	}
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
new file mode 100755
index 0000000..a04b50c
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ConformanceTestSet.java
@@ -0,0 +1,171 @@
+/*
+ *                        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.xacmlatt.pdp.test.conformance;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * ConformanceTestSet represents a collection of <code>ConformanceTest</code>s ordered by the test name.  It has methods for
+ * scanning a directory to generate an ordered set.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ConformanceTestSet {
+	private static final Log logger						= LogFactory.getLog(ConformanceTestSet.class);
+	private List<ConformanceTest> listConformanceTests	= new ArrayList<ConformanceTest>();
+	
+	protected List<ConformanceTest> getListConformanceTests() {
+		return this.listConformanceTests;
+	}
+	
+	protected ConformanceTestSet() {
+		
+	}
+	
+	private static String getTestName(String fileName, int itemPos) {
+		return (itemPos == 0 ? "NULL" : fileName.substring(0, itemPos));
+	}
+	
+	private static String getTestName(File file) {
+		String fileName	= file.getName();
+		int itemPos		= fileName.indexOf("Policy");
+		if (itemPos >= 0) {
+			return getTestName(fileName, itemPos);
+		} else if ((itemPos = fileName.indexOf("Request")) >= 0) {
+			return getTestName(fileName, itemPos);
+		} else if ((itemPos = fileName.indexOf("Response")) >= 0) {
+			return getTestName(fileName, itemPos);
+		} else if ((itemPos = fileName.indexOf("Repository")) >= 0) {
+			return getTestName(fileName, itemPos);
+		} else {
+			return null;
+		}
+	}
+	
+	public static ConformanceTestSet loadDirectory(File fileDir) throws IOException {
+		final Map<String,ConformanceTest> mapConformanceTests	= new HashMap<String,ConformanceTest>();
+		
+		Files.walkFileTree(fileDir.toPath(), new FileVisitor<Path>() {
+			@Override
+			public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+				logger.info("Scanning directory " + dir.getFileName());
+				return FileVisitResult.CONTINUE;
+			}
+
+			@Override
+			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+				File fileVisited	= file.toFile();
+				String fileName		= fileVisited.getName();
+				if (fileName.endsWith(".xml") || fileName.endsWith(".properties")) {
+					String testName	= getTestName(fileVisited);
+					if (testName != null) {
+						ConformanceTest conformanceTest	= mapConformanceTests.get(testName);
+						if (conformanceTest == null) {
+							logger.info("Added test " + testName);
+							conformanceTest	= new ConformanceTest(testName);
+							mapConformanceTests.put(testName, conformanceTest);
+						}
+						if (fileName.endsWith("Policy.xml")) {
+							conformanceTest.getRepository().addRootPolicy(fileVisited);
+						} else if (fileName.endsWith("Repository.properties")) {
+							conformanceTest.getRepository().load(fileVisited);
+						} else if (fileName.endsWith("Request.xml")) {
+							conformanceTest.setRequest(fileVisited);
+						} else if (fileName.endsWith("Response.xml")) {
+							conformanceTest.setResponse(fileVisited);
+						}
+					}
+				}
+				return FileVisitResult.CONTINUE;
+			}
+
+			@Override
+			public FileVisitResult visitFileFailed(Path file, IOException exc) 	throws IOException {
+				logger.warn("Skipped " + file.getFileName());
+				return FileVisitResult.CONTINUE;
+			}
+
+			@Override
+			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+				return FileVisitResult.CONTINUE;
+			}
+		});
+		
+		/*
+		 * Sort the keyset and pull out the tests that have the required components
+		 */
+		List<String> listTestNames	= new ArrayList<String>();
+		listTestNames.addAll(mapConformanceTests.keySet());
+		Collections.sort(listTestNames);
+		
+		ConformanceTestSet conformanceTestSet	= new ConformanceTestSet();
+		Iterator<String> iterTestNames	= listTestNames.iterator();
+		while (iterTestNames.hasNext()) {
+			ConformanceTest	conformanceTest	= mapConformanceTests.get(iterTestNames.next());
+			if (conformanceTest.isComplete()) {
+				conformanceTestSet.addConformanceTest(conformanceTest);
+				logger.debug("Added conformance test " + conformanceTest.getTestName());
+			} else {
+				logger.warn("Incomplete conformance test " + conformanceTest.getTestName());
+			}
+		}
+		
+		return conformanceTestSet;
+		
+	}
+
+	public Iterator<ConformanceTest> getConformanceTests() {
+		return this.listConformanceTests.iterator();
+	}
+	
+	public void addConformanceTest(ConformanceTest conformanceTest) {
+		this.listConformanceTests.add(conformanceTest);
+	}
+	
+	public void addConformanceTestSet(ConformanceTestSet conformanceTestSet) {
+		this.listConformanceTests.addAll(conformanceTestSet.getListConformanceTests());
+	}
+	
+	public static void main(String[] args) {
+		for (String dir : args) {
+			try {
+				ConformanceTestSet conformanceTestSet			= ConformanceTestSet.loadDirectory(new File(dir));
+				Iterator<ConformanceTest> iterConformanceTests	= conformanceTestSet.getConformanceTests();
+				if (iterConformanceTests == null) {
+					System.out.println("No tests found in " + dir);
+				} else {
+					System.out.println("Tests found in " + dir);
+					while (iterConformanceTests.hasNext()) {
+						System.out.println(iterConformanceTests.next().toString());
+					}
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace(System.err);
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
new file mode 100755
index 0000000..00db0dc
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResponseMatchResult.java
@@ -0,0 +1,128 @@
+/*
+ *                        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.xacmlatt.pdp.test.conformance;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.att.research.xacml.api.Response;
+import com.att.research.xacml.api.Result;
+
+/**
+ * ResponseMatchResult provides information about how a {@link com.att.research.xacml.api.Response} object matches
+ * another <code>Response</code> object.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ResponseMatchResult {
+	private List<ResultMatchResult>	resultMatchResults	= new ArrayList<ResultMatchResult>();
+	
+	private boolean bAssociatedAdviceMatches			= true;
+	private boolean bAttributesMatch					= true;
+	private boolean bDecisionsMatch						= true;
+	private boolean bStatusCodesMatch					= true;
+	private boolean bObligationsMatch					= true;
+	private boolean bPolicyIdentifiersMatch				= true;
+	private boolean bPolicySetIdentifiersMatch			= true;
+	private boolean bNumResultsMatch					= true;
+	private boolean bUnknownFunction;
+	
+	protected void addResultMatchResult(ResultMatchResult resultMatchResult) {
+		this.resultMatchResults.add(resultMatchResult);
+		this.bAssociatedAdviceMatches	= resultMatchResult.associatedAdviceMatches() && this.bAssociatedAdviceMatches;
+		this.bAttributesMatch			= resultMatchResult.attributesMatch() && this.bAttributesMatch;
+		this.bDecisionsMatch			= resultMatchResult.decisionsMatch() && this.bDecisionsMatch;
+		this.bStatusCodesMatch			= resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch;
+		this.bObligationsMatch			= resultMatchResult.obligationsMatch() && this.bObligationsMatch;
+		this.bPolicyIdentifiersMatch	= resultMatchResult.policyIdentifiersMatch() && this.bPolicyIdentifiersMatch;
+		this.bPolicySetIdentifiersMatch	= resultMatchResult.policySetIdentifiersMatch() && this.bPolicySetIdentifiersMatch;
+		this.bUnknownFunction			= resultMatchResult.unknownFunction() || this.bUnknownFunction;
+	}
+	
+	protected void setNumResultsMatch(boolean b) {
+		this.bNumResultsMatch	= b;
+	}
+	
+	public ResponseMatchResult() {
+	}
+	
+	public static ResponseMatchResult newInstance(Response response1, Response response2) {
+		ResponseMatchResult responseMatchResult	= new ResponseMatchResult();
+
+		Collection<Result> listResultsResponse1	= response1.getResults();
+		Collection<Result> listResultsResponse2	= response2.getResults();
+		if (listResultsResponse1.size() == 1 && listResultsResponse2.size() == 1) {
+			/*
+			 * Just add a single ResultMatchResult comparing the results in the two responses
+			 */
+			responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(listResultsResponse1.iterator().next(), listResultsResponse2.iterator().next()));
+		} else {
+			/*
+			 * Iterate over all of the results in the two responses and match them
+			 */
+			Iterator<Result> iterResponse1Results	= listResultsResponse1.iterator();
+			Iterator<Result> iterResponse2Results	= listResultsResponse2.iterator();
+			while ((iterResponse1Results != null && iterResponse1Results.hasNext()) || (iterResponse2Results != null && iterResponse2Results.hasNext())) {
+				Result result1	= (iterResponse1Results != null && iterResponse1Results.hasNext() ? iterResponse1Results.next() : null);
+				Result result2	= (iterResponse2Results != null && iterResponse2Results.hasNext() ? iterResponse2Results.next() : null);
+				if ((result1 == null || result2 == null) && responseMatchResult.numResultsMatch()) {
+					responseMatchResult.setNumResultsMatch(false);
+				}
+				responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(result1, result2));
+			}
+		}
+		return responseMatchResult;
+	}
+
+	public Iterator<ResultMatchResult> getResultMatchResults() {
+		return this.resultMatchResults.iterator();
+	}
+	
+	public boolean numResultsMatch() {
+		return this.bNumResultsMatch;
+	}
+	
+	public boolean associatedAdviceMatches() {
+		return this.bAssociatedAdviceMatches;
+	}
+	
+	public boolean attributesMatch() {
+		return this.bAttributesMatch;
+	}
+	
+	public boolean decisionsMatch() {
+		return this.bDecisionsMatch;
+	}
+	
+	public boolean obligationsMatch() {
+		return this.bObligationsMatch;
+	}
+	
+	public boolean policyIdentifiersMatch() {
+		return this.bPolicyIdentifiersMatch;
+	}
+	
+	public boolean policySetIdentifiersMatch() {
+		return this.bPolicySetIdentifiersMatch;
+	}
+	
+	public boolean statusCodesMatch() {
+		return this.bStatusCodesMatch;
+	}
+	
+	public boolean unknownFunction() {
+		return this.bUnknownFunction;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
new file mode 100755
index 0000000..645a755
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/ResultMatchResult.java
@@ -0,0 +1,127 @@
+/*
+ *                        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.xacmlatt.pdp.test.conformance;
+
+import com.att.research.xacml.api.Result;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.util.ListUtil;
+
+/**
+ * ResultMatchResult provides information about how well a {@link com.att.research.xacml.api.Result} object matches
+ * another <code>Result</code> object.
+ * 
+ * @author car
+ * @version $Revision: 1.1 $
+ */
+public class ResultMatchResult {
+	private boolean bAssociatedAdviceMatches	= true;
+	private boolean bAttributesMatch			= true;
+	private boolean bDecisionsMatch				= true;
+	private boolean bObligationsMatch			= true;
+	private boolean bPolicyIdentifiersMatch		= true;
+	private boolean bPolicySetIdentifiersMatch	= true;
+	private boolean bStatusCodesMatch			= true;
+	private boolean bUnknownFunction			= false;
+	
+	protected void setAssociatedAdviceMatches(boolean b) {
+		this.bAssociatedAdviceMatches	= b;
+	}
+	protected void setAttributesMatch(boolean b) {
+		this.bAttributesMatch	= b;
+	}
+	protected void setDecisionsMatch(boolean b) {
+		this.bDecisionsMatch	= b;
+	}
+	protected void setObligationsMatch(boolean b) {
+		this.bObligationsMatch	= b;
+	}
+	protected void setPolicyIdentifiersMatch(boolean b) {
+		this.bPolicyIdentifiersMatch	= b;
+	}
+	protected void setPolicySetIdentifiersMatch(boolean b) {
+		this.bPolicySetIdentifiersMatch	= b;
+	}
+	protected void setStatusCodesMatch(boolean b) {
+		this.bStatusCodesMatch	= b;
+	}
+	protected void setUnknownFunction(boolean b) {
+		this.bUnknownFunction	= b;
+	}
+	
+	public ResultMatchResult() {
+	}
+	
+	public static ResultMatchResult newInstance(Result result1, Result result2) {
+		ResultMatchResult resultMatchResult	= new ResultMatchResult();
+		if (result2 != null && result2.getStatus() != null && 
+			result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_CODE_PROCESSING_ERROR) && 
+			result2.getStatus().getStatusMessage() != null &&
+			result2.getStatus().getStatusMessage().contains("Unknown Function")
+			) {
+			resultMatchResult.setUnknownFunction(true);
+		}
+		if (result1 == null || result2 == null) {
+			resultMatchResult.setAssociatedAdviceMatches(false);
+			resultMatchResult.setAttributesMatch(false);
+			resultMatchResult.setDecisionsMatch(false);
+			resultMatchResult.setObligationsMatch(false);
+			resultMatchResult.setPolicyIdentifiersMatch(false);
+			resultMatchResult.setPolicySetIdentifiersMatch(false);
+			resultMatchResult.setStatusCodesMatch(false);
+		} else {
+			resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllowNulls(result1.getAssociatedAdvice(), result2.getAssociatedAdvice()));
+			resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(result1.getAttributes(), result2.getAttributes()));
+			resultMatchResult.setDecisionsMatch(result1.getDecision() == result2.getDecision());
+			resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(result1.getObligations(), result2.getObligations()));
+			resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicyIdentifiers(), result2.getPolicyIdentifiers()));
+			resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicySetIdentifiers(), result2.getPolicySetIdentifiers()));
+			if (result1.getStatus() == null || result1.getStatus().getStatusCode() == null || result2.getStatus() == null || result2.getStatus().getStatusCode() == null) {
+				resultMatchResult.setStatusCodesMatch(false);
+			} else {
+				resultMatchResult.setStatusCodesMatch(result1.getStatus().getStatusCode().equals(result2.getStatus().getStatusCode()));
+			}
+		}
+		return resultMatchResult;
+	}
+	
+	public boolean associatedAdviceMatches() {
+		return this.bAssociatedAdviceMatches;
+	}
+	
+	public boolean attributesMatch() {
+		return this.bAttributesMatch;
+	}
+	
+	public boolean decisionsMatch() {
+		return this.bDecisionsMatch;
+	}
+	
+	public boolean obligationsMatch() {
+		return this.bObligationsMatch;
+	}
+	
+	public boolean policyIdentifiersMatch() {
+		return this.bPolicyIdentifiersMatch;
+	}
+	
+	public boolean policySetIdentifiersMatch() {
+		return this.bPolicySetIdentifiersMatch;
+	}
+	
+	public boolean statusCodesMatch() {
+		return this.bStatusCodesMatch;
+	}
+	
+	public boolean unknownFunction() {
+		return this.bUnknownFunction;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
new file mode 100755
index 0000000..b3e6cc4
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomDataTypeFactory.java
@@ -0,0 +1,78 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeFactory;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.datatypes.DataTypes;
+
+public class CustomDataTypeFactory extends DataTypeFactory {
+	private static final Map<Identifier,DataType<?>> mapIdentifiersToDataTypes	= new HashMap<Identifier,DataType<?>>();
+	private static boolean mapNeedsInit												= true;
+	
+	public static final DataTypePrivateKey				DT_PRIVATEKEY				= DataTypePrivateKey.newInstance();
+	public static final DataTypePublicKey				DT_PUBLICKEY				= DataTypePublicKey.newInstance();
+	
+	private static void registerDataType(DataType<?> dataType) {
+		if (dataType != null && dataType.getId() != null) {
+			mapIdentifiersToDataTypes.put(dataType.getId(), dataType);
+		}
+	}
+	
+	private static void initMap() {
+		if (mapNeedsInit) {
+			synchronized(mapIdentifiersToDataTypes) {
+				if (mapNeedsInit) {
+					registerDataType(DataTypes.DT_ANYURI);
+					registerDataType(DataTypes.DT_BASE64BINARY);
+					registerDataType(DataTypes.DT_BOOLEAN);
+					registerDataType(DataTypes.DT_DATE);
+					registerDataType(DataTypes.DT_DATETIME);
+					registerDataType(DataTypes.DT_DAYTIMEDURATION);
+					registerDataType(DataTypes.DT_DNSNAME);
+					registerDataType(DataTypes.DT_DOUBLE);
+					registerDataType(DataTypes.DT_HEXBINARY);
+					registerDataType(DataTypes.DT_INTEGER);
+					registerDataType(DataTypes.DT_IPADDRESS);
+					registerDataType(DataTypes.DT_RFC822NAME);
+					registerDataType(DataTypes.DT_STRING);
+					registerDataType(DataTypes.DT_TIME);
+					registerDataType(DataTypes.DT_X500NAME);
+					registerDataType(DataTypes.DT_XPATHEXPRESSION);
+					registerDataType(DataTypes.DT_YEARMONTHDURATION);
+					//
+					// These are the custom data types!
+					//
+					registerDataType(DT_PRIVATEKEY);
+					registerDataType(DT_PUBLICKEY);
+					//
+					// Done
+					//
+					mapNeedsInit	= false;
+				}
+			}
+		}
+	}
+
+	public CustomDataTypeFactory() {
+		initMap();
+	}
+
+	@Override
+	public DataType<?> getDataType(Identifier dataTypeId) {
+		return mapIdentifiersToDataTypes.get(dataTypeId);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
new file mode 100755
index 0000000..dd4decb
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunctionDefinitionFactory.java
@@ -0,0 +1,80 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
+import com.att.research.xacmlatt.pdp.std.StdFunctions;
+import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly;
+
+public class CustomFunctionDefinitionFactory extends FunctionDefinitionFactory {
+	private static Map<Identifier,FunctionDefinition> 	mapFunctionDefinitions	= new HashMap<Identifier,FunctionDefinition>();
+	private static boolean								needMapInit				= true;
+	
+	public static final Identifier ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:privatekey-one-and-only");
+	public static final Identifier ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:publickey-one-and-only");
+	
+	public static final FunctionDefinition	FD_PRIVATEKEY_ONE_AND_ONLY	= new FunctionDefinitionBagOneAndOnly<PrivateKey>(ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY, DataTypePrivateKey.newInstance());
+	public static final FunctionDefinition	FD_PUBLICKEY_ONE_AND_ONLY	= new FunctionDefinitionBagOneAndOnly<PublicKey>(ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY, DataTypePublicKey.newInstance());
+
+	private static void register(FunctionDefinition functionDefinition) {
+		mapFunctionDefinitions.put(functionDefinition.getId(), functionDefinition);
+	}
+		
+	private static void initMap() {
+		if (needMapInit) {
+			synchronized(mapFunctionDefinitions) {
+				if (needMapInit) {
+					needMapInit	= false;
+					Field[] declaredFields	= StdFunctions.class.getDeclaredFields();
+					for (Field field : declaredFields) {
+						if (Modifier.isStatic(field.getModifiers()) && 
+							field.getName().startsWith(StdFunctions.FD_PREFIX) &&
+							FunctionDefinition.class.isAssignableFrom(field.getType()) &&
+							Modifier.isPublic(field.getModifiers())
+						) {
+							try {
+								register((FunctionDefinition)(field.get(null)));
+							} catch (IllegalAccessException ex) {
+								
+							}
+						}
+					}
+					//
+					// Our custom function
+					//
+					register(FunctionDefinitionDecrypt.newInstance());
+					register(FD_PRIVATEKEY_ONE_AND_ONLY);
+					register(FD_PUBLICKEY_ONE_AND_ONLY);
+				}
+			}
+		}
+	}
+	
+	public CustomFunctionDefinitionFactory() {
+		initMap();
+	}
+
+	@Override
+	public FunctionDefinition getFunctionDefinition(Identifier functionId) {
+		return mapFunctionDefinitions.get(functionId);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
new file mode 100755
index 0000000..4e12aef
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePrivateKey.java
@@ -0,0 +1,44 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.security.PrivateKey;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.datatypes.DataTypeBase;
+
+public class DataTypePrivateKey extends DataTypeBase<PrivateKey> {
+	public static final Identifier DT_PRIVATEKEY = new IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:private");
+	private static final DataTypePrivateKey singleInstance = new DataTypePrivateKey();
+	
+	private DataTypePrivateKey() {
+		super(DT_PRIVATEKEY, PrivateKey.class);
+	}
+
+	public static DataTypePrivateKey newInstance() {
+		return singleInstance;
+	}
+	
+	@Override
+	public PrivateKey convert(Object source) throws DataTypeException {
+		if (source == null || (source instanceof PrivateKey) ) {
+			return (PrivateKey) source;
+		} else if (source instanceof byte[]) {
+			return (PrivateKey) source;
+		} else if (source instanceof String) {
+			return (PrivateKey) (Object) ((String) source).getBytes();
+		}
+		throw new DataTypeException(this, "Failed to convert \"" + source.getClass().getCanonicalName());				
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
new file mode 100755
index 0000000..d40ee82
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePublicKey.java
@@ -0,0 +1,44 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.security.PublicKey;
+
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.datatypes.DataTypeBase;
+
+public class DataTypePublicKey extends DataTypeBase<PublicKey> {
+	public static final Identifier DT_PUBLICKEY = new IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:public");
+	private static final DataTypePublicKey singleInstance = new DataTypePublicKey();
+	
+	public DataTypePublicKey() {
+		super(DT_PUBLICKEY, PublicKey.class);
+	}
+	
+	public static DataTypePublicKey newInstance() {
+		return singleInstance;
+	}
+
+	@Override
+	public PublicKey convert(Object source) throws DataTypeException {
+		if (source == null || (source instanceof PublicKey) ) {
+			return (PublicKey) source;
+		} else if (source instanceof byte[]) {
+			return (PublicKey) source;
+		} else if (source instanceof String) {
+			return (PublicKey) (Object) ((String) source).getBytes();
+		}
+		throw new DataTypeException(this, "Failed to convert \"" + source.getClass().getCanonicalName());				
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
new file mode 100755
index 0000000..d51c73d
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDefinitionDecrypt.java
@@ -0,0 +1,152 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.List;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Identifier;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdStatus;
+import com.att.research.xacml.std.StdStatusCode;
+import com.att.research.xacml.std.datatypes.DataTypeHexBinary;
+import com.att.research.xacml.std.datatypes.DataTypeString;
+import com.att.research.xacml.std.datatypes.HexBinary;
+import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
+import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
+import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
+import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
+import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
+
+public class FunctionDefinitionDecrypt implements FunctionDefinition {
+	public static final Identifier FD_RSA_DECRYPT = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decrypt");
+	private static final FunctionDefinitionDecrypt singleInstance = new FunctionDefinitionDecrypt();
+	
+	public static FunctionDefinitionDecrypt newInstance() {
+		return singleInstance;
+	}
+
+	@Override
+	public Identifier getId() {
+		return FD_RSA_DECRYPT;
+	}
+
+	@Override
+	public Identifier getDataTypeId() {
+		return XACML3.ID_DATATYPE_STRING;
+	}
+
+	@Override
+	public boolean returnsBag() {
+		return false;
+	}
+
+	@Override
+	public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
+		if (arguments == null || arguments.size() < 2) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expecting 2 arguments."));
+		}
+		//
+		// What is the first argument?
+		//
+		FunctionArgument arg0 = arguments.get(0);
+		if (arg0.isBag()) {
+			//
+			// We don't support bags right now
+			//
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 0."));
+		}
+		if (arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY) == false) {
+			//
+			// Should be a String
+			//
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expected a Hex Binary for argument 0."));
+		}
+		//
+		// Convert the argument
+		//
+		ConvertedArgument<HexBinary> data = new ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(), false);
+		if (! data.isOk()) {
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, argument 0 failed to convert to Hex Binary."));
+		}
+		//
+		// Ok - check the 2nd argument
+		//
+		FunctionArgument arg1 = arguments.get(1);
+		if (arg1.isBag()) {
+			//
+			// We don't support bags right now
+			//
+			return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 1."));
+		}
+		if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY) ||
+				arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
+			//
+			// Ok - let's try to decrypt
+			//
+			Cipher cipher;
+			try {
+				cipher = Cipher.getInstance("RSA");
+				if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY)) {
+					//
+					// Using the private key
+					//
+					DataType<PrivateKey> pkDatatype = DataTypePrivateKey.newInstance();
+					ConvertedArgument<PrivateKey> privateKey = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
+					if ( ! privateKey.isOk()) {
+						return ExpressionResult.newError(new StdStatus(privateKey.getStatus().getStatusCode(), "Decrypt: " + privateKey.getStatus().getStatusMessage()));
+					}
+					//
+					// Setup decryption
+					//
+					cipher.init(Cipher.DECRYPT_MODE, privateKey.getValue());
+				} else if (arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
+					//
+					// Using the private key
+					//
+					DataType<PublicKey> pkDatatype = DataTypePublicKey.newInstance();
+					ConvertedArgument<PublicKey> publicKey = new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
+					if ( ! publicKey.isOk()) {
+						return ExpressionResult.newError(new StdStatus(publicKey.getStatus().getStatusCode(), "Decrypt: " + publicKey.getStatus().getStatusMessage()));
+					}
+					//
+					// Setup decryption
+					//
+					cipher.init(Cipher.DECRYPT_MODE, publicKey.getValue());
+				}
+				//
+				// Do the decryption
+				//
+				byte[] decryptedData = cipher.doFinal(data.getValue().getData());
+				String decryptedString = new String(decryptedData);
+				//
+				// All good, return the decrypted string
+				//
+				return ExpressionResult.newSingle(DataTypeString.newInstance().createAttributeValue(decryptedString));
+			} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | DataTypeException e) {
+				return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed: " + e.getLocalizedMessage()));
+			}
+		}		
+		return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expecting public/private key datatype for argument 1."));
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/94fcdd90/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
new file mode 100755
index 0000000..df93001
--- /dev/null
+++ b/openaz-xacml-test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom.java
@@ -0,0 +1,384 @@
+/*
+ *                        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.xacmlatt.pdp.test.custom;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.att.research.xacml.api.AttributeValue;
+import com.att.research.xacml.api.DataType;
+import com.att.research.xacml.api.DataTypeException;
+import com.att.research.xacml.api.Request;
+import com.att.research.xacml.api.RequestAttributes;
+import com.att.research.xacml.api.XACML3;
+import com.att.research.xacml.api.pep.PEPException;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.std.StdMutableAttribute;
+import com.att.research.xacml.std.StdMutableRequest;
+import com.att.research.xacml.std.StdMutableRequestAttributes;
+import com.att.research.xacml.std.dom.DOMStructureException;
+import com.att.research.xacml.std.json.JSONStructureException;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacmlatt.pdp.test.TestBase;
+
+/**
+ * TestCustom is an application that tests the extensibility and configurability of the AT&T XACML API.
+ * 
+ * It creates a custom datatype definition factory that adds in custom data types for RSA
+ * PublicKey and PrivateKey.
+ * 
+ * It creates a custom function definition factory that adds in custom decryption function for decrypting data. It
+ * also derives and loads custom functions for the RSA public/private key datatypes for the bag function: one-and-only. 
+ * 
+ * @author pameladragosh
+ *
+ */
+public class TestCustom extends TestBase {
+	private static final Log logger	= LogFactory.getLog(TestCustom.class);
+	
+	//
+	// Our public's
+	//
+	public static final String ALGORITHM = "RSA";
+	public static final String PRIVATEKEY_FILE = "PrivateKey.key";
+	public static final String PUBLICKEY_FILE = "PublicKey.key";
+	
+	public static final String DECRYPTION_INPUT_STRING = "This is the SECRET value!";
+	
+	public static final String DECRYPTION_INPUT_ID = "com:att:research:xacml:test:custom:encrypted-data";
+	//
+	// Our keys
+	//
+	protected PublicKey publicKey = null;
+	protected PrivateKey privateKey = null;
+	//
+	// Our command line parameters
+	//
+	public static final String OPTION_GENERATE = "generate";
+
+	static {
+		options.addOption(new Option(OPTION_GENERATE, false, "Generate a private/public key pair."));
+	}
+	
+	/**
+	 * This function generates the public/private key pair. Should never have to call this again, this was
+	 * called once to generate the keys. They were saved into the testsets/custom/datatype-function sub-directory.
+	 */
+	public void generateKeyPair() {
+		//
+		// Generate a RSA private/public key pair
+		//
+		KeyPairGenerator keyGen;
+		try {
+			keyGen = KeyPairGenerator.getInstance(ALGORITHM);
+		} catch (NoSuchAlgorithmException e) {
+			logger.error("failed to generate keypair: " + e);
+			return;
+		}
+		keyGen.initialize(1024);
+		final KeyPair key = keyGen.generateKeyPair();
+		//
+		// Save the keys to disk
+		//
+		Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
+		try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
+			os.writeObject(key.getPrivate());
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		file = Paths.get(this.directory, PUBLICKEY_FILE);
+		try (ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(file))) {
+			os.writeObject(key.getPublic());
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public TestCustom(String[] args) throws ParseException, MalformedURLException, HelpException {
+		super(args);
+	}
+	
+	/* (non-Javadoc)
+	 * 
+	 * Simply look for command line option: -generate
+	 * This generates the public/private key. Shouldn't need to call it again, the keys have
+	 * already been generated and saved.
+	 * 
+	 * @see com.att.research.xacmlatt.pdp.test.TestBase#parseCommands(java.lang.String[])
+	 */
+	@Override
+	protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException {
+		//
+		// Have our parent class parse its options out
+		//
+		super.parseCommands(args);
+		//
+		// Parse the command line options
+		//
+		CommandLine cl;
+		cl = new GnuParser().parse(options, args);
+		if (cl.hasOption(OPTION_GENERATE)) {
+			//
+			// Really only need to do this once to setup the test.
+			//
+			this.generateKeyPair();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * 
+	 * After our parent class configure's itself, all this needs to do is read in
+	 * the public/private key's into objects.
+	 * 
+	 * @see com.att.research.xacmlatt.pdp.test.TestBase#configure()
+	 */
+	@Override
+	protected void configure() throws FactoryException {
+		//
+		// Have our super do its thing
+		//
+		super.configure();
+		//
+		// Read in the public key
+		//
+		try {
+			this.publicKey = (PublicKey) new ObjectInputStream(Files.newInputStream(Paths.get(this.directory, PUBLICKEY_FILE))).readObject();
+		} catch (ClassNotFoundException | IOException e) {
+			logger.error(e);
+		}
+		//
+		// Read in the private key
+		//
+		try {
+			this.privateKey = (PrivateKey) new ObjectInputStream(Files.newInputStream(Paths.get(this.directory, PRIVATEKEY_FILE))).readObject();
+		} catch (ClassNotFoundException | IOException e) {
+			logger.error(e);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * 
+	 * Here we add 2 attributes into the request: 1) the private key, and 2) a String that was encrypted using the public key.
+	 * 
+	 * The goal is to have the custom decrypt function use the private key to decrypt that string.
+	 * 
+	 * @see com.att.research.xacmlatt.pdp.test.TestBase#generateRequest(java.nio.file.Path, java.lang.String)
+	 */
+	@Override
+	protected Request generateRequest(Path file, String group) throws JSONStructureException, DOMStructureException, PEPException {
+		//
+		// Have our super class do its work
+		//
+		Request oldRequest = super.generateRequest(file, group);
+		//
+		// Copy the request attributes
+		//
+		List<StdMutableRequestAttributes> attributes = new ArrayList<StdMutableRequestAttributes>();
+		for (RequestAttributes a : oldRequest.getRequestAttributes()) {
+			attributes.add(new StdMutableRequestAttributes(a));
+		}
+		//
+		// We are supplying the private key as an attribute for the decryption function to use:
+		//
+		// (NOTE: Ideally this would be provided by a custom PIP provider, not the PEP)
+		//
+		// ID=com:att:research:xacml:test:custom:privatekey
+		// Issuer=com:att:research:xacml:test:custom
+		// Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+		// Datatype=urn:com:att:research:xacml:custom:3.0:rsa:private
+		//
+		DataType<?> dtExtended = dataTypeFactory.getDataType(DataTypePrivateKey.DT_PRIVATEKEY);
+		if (dtExtended == null) {
+			logger.error("Failed to get private key datatype.");
+			return null;
+		}
+		//
+		// Create the attribute value
+		//
+		try {
+			AttributeValue<?> attributeValue = dtExtended.createAttributeValue(this.privateKey);					
+			//
+			// Create the attribute
+			//
+			StdMutableAttribute newAttribute = new StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
+																		new IdentifierImpl("com:att:research:xacml:test:custom:privatekey"),
+																		attributeValue,
+																		"com:att:research:xacml:test:custom",
+																		false);
+			boolean added = false;
+			for (StdMutableRequestAttributes a : attributes) {
+				//
+				// Does the category exist?
+				//
+				if (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+					//
+					// Yes - add in the new attribute value
+					//
+					a.add(newAttribute);
+					added = true;
+					break;
+				}
+			}
+			if (added == false) {
+				//
+				// New category - create it and add it in
+				//
+				StdMutableRequestAttributes a = new StdMutableRequestAttributes(); 
+				a.setCategory(newAttribute.getCategory());
+				a.add(newAttribute);
+				attributes.add(a);
+			}
+		} catch (DataTypeException e) {
+			logger.error(e);
+			return null;
+		}
+		//
+		// We are also supplying this attribute which is the secret text encrypted with
+		// the public key.
+		//
+		// ID=com:att:research:xacml:test:custom:encrypted-data
+		// Issuer=
+		// Category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+		// Datatype=http://www.w3.org/2001/XMLSchema#hexBinary
+		//
+		// Encrypt it
+		//
+		byte[] encryptedData = null;
+		try {
+			Cipher cipher = Cipher.getInstance(ALGORITHM);
+			cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
+			//
+			// This is just a hack to test a decryption of the wrong value.
+			//
+			if (group.equals("Permit")) {
+				encryptedData = cipher.doFinal(DECRYPTION_INPUT_STRING.getBytes());
+			} else {
+				encryptedData = cipher.doFinal("This is NOT the secret".getBytes());
+			}
+		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
+			logger.error(e);
+			return null;
+		}
+		//
+		// Sanity check (for the Permit request)
+		//
+		try {
+			if (group.equals("Permit")) {
+				Cipher cipher = Cipher.getInstance(ALGORITHM);
+				cipher.init(Cipher.DECRYPT_MODE, this.privateKey);
+				byte[] decryptedData = cipher.doFinal(encryptedData);
+				if (new String(decryptedData).equals(DECRYPTION_INPUT_STRING)) {
+					logger.info("Sanity check passed: decrypted the encrypted data.");
+				} else {
+					logger.error("Sanity check failed to decrypt the encrypted data.");
+					return null;
+				}
+			}
+		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
+			logger.error(e);
+		}
+		//
+		// Get our datatype factory
+		//
+		dtExtended = dataTypeFactory.getDataType(XACML3.ID_DATATYPE_HEXBINARY);
+		if (dtExtended == null) {
+			logger.error("Failed to get hex binary datatype.");
+			return null;
+		}
+		//
+		// Create the attribute value
+		//
+		try {
+			AttributeValue<?> attributeValue = dtExtended.createAttributeValue(encryptedData);					
+			//
+			// Create the attribute
+			//
+			StdMutableAttribute newAttribute = new StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
+																		new IdentifierImpl("com:att:research:xacml:test:custom:encrypted-data"),
+																		attributeValue,
+																		null,
+																		false);
+			boolean added = false;
+			for (StdMutableRequestAttributes a : attributes) {
+				//
+				// Does the category exist?
+				//
+				if (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+					//
+					// Yes - add in the new attribute value
+					//
+					a.add(newAttribute);
+					added = true;
+					break;
+				}
+			}
+			if (added == false) {
+				//
+				// New category - create it and add it in
+				//
+				StdMutableRequestAttributes a = new StdMutableRequestAttributes(); 
+				a.setCategory(newAttribute.getCategory());
+				a.add(newAttribute);
+				attributes.add(a);
+			}
+		} catch (DataTypeException e) {
+			logger.error(e);
+			return null;
+		}
+		//
+		// Now form our final request
+		//
+		StdMutableRequest newRequest = new StdMutableRequest();
+		newRequest.setCombinedDecision(oldRequest.getCombinedDecision());
+		newRequest.setRequestDefaults(oldRequest.getRequestDefaults());
+		newRequest.setReturnPolicyIdList(oldRequest.getReturnPolicyIdList());
+		newRequest.setStatus(oldRequest.getStatus());
+		for (StdMutableRequestAttributes a : attributes) {
+			newRequest.add(a);
+		}
+		return newRequest;
+	}
+
+	public static void main(String[] args) {
+		try {
+			new TestCustom(args).run();
+		} catch (ParseException | IOException | FactoryException e) {
+			logger.error(e);
+		} catch (HelpException e) {
+		}		
+	}
+
+}


Re: [10/51] [partial] incubator-openaz git commit: Initial seed of merged of AT&T and JP Morgan code

Posted by Colm O hEigeartaigh <co...@apache.org>.
I've raised an issue with INFRA:
https://issues.apache.org/jira/servicedesk/customer/portal/1/INFRA-9439

Colm.

On Mon, Apr 13, 2015 at 8:26 PM, Hal Lockhart <ha...@oracle.com>
wrote:

> I thought messages of this type would go to commits or some other list.
> This will make dev unusable.
>
> Hal
>
> > -----Original Message-----
> > From: pdragosh@apache.org [mailto:pdragosh@apache.org]
> > Sent: Monday, April 13, 2015 11:38 AM
> > To: dev@openaz.incubator.apache.org
> > Subject: [10/51] [partial] incubator-openaz git commit: Initial seed of
> > merged of AT&T and JP Morgan code
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTest.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTest.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTest.java
> > new file mode 100755
> > index 0000000..be0b46f
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTest.java
> > @@ -0,0 +1,95 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.conformance;
> > +
> > +import java.io.File;
> > +
> > +/**
> > + * ConformanceTest represents a collection of XACML files with a root
> > Policy document, optional referenced Policy documents, a Request, and a
> > Response.
> > + *
> > + * @author car
> > + * @version $Revision: 1.2 $
> > + */
> > +public class ConformanceTest {
> > +     private String testName;
> > +     private File request;
> > +     private File response;
> > +     private ConformanceRepository repository;
> > +
> > +     public ConformanceTest(String name, ConformanceRepository
> > conformanceRepository, File fileRequest, File fileResponse) {
> > +             this.testName   = name;
> > +             this.request    = fileRequest;
> > +             this.response   = fileResponse;
> > +             this.repository = conformanceRepository;
> > +     }
> > +
> > +     public ConformanceTest(String name) {
> > +             this.testName   = name;
> > +     }
> > +
> > +     public String getTestName() {
> > +             return this.testName;
> > +     }
> > +     public void setTestName(String s) {
> > +             this.testName   = s;
> > +     }
> > +     public ConformanceRepository getRepository() {
> > +             if (this.repository == null) {
> > +                     this.repository = new ConformanceRepository();
> > +             }
> > +             return this.repository;
> > +     }
> > +     public File getRequest() {
> > +             return this.request;
> > +     }
> > +     public void setRequest(File f) {
> > +             this.request    = f;
> > +     }
> > +     public File getResponse() {
> > +             return this.response;
> > +     }
> > +     public void setResponse(File f) {
> > +             this.response   = f;
> > +     }
> > +
> > +     public boolean isComplete() {
> > +             return this.getTestName() != null && this.getRepository()
> > != null && this.getRepository().hasRootPolicy() && this.getRequest() !=
> > null && this.getResponse() != null;
> > +     }
> > +
> > +     @Override
> > +     public String toString() {
> > +             StringBuilder stringBuilder     = new StringBuilder();
> > +             boolean needColon                       = false;
> > +             if (this.getTestName() != null) {
> > +                     stringBuilder.append(this.getTestName());
> > +                     needColon       = true;
> > +             }
> > +             if (this.getRepository() != null) {
> > +
> > +             }
> > +             if (this.getRequest() != null) {
> > +                     if (needColon) {
> > +                             stringBuilder.append(':');
> > +                     }
> > +                     stringBuilder.append(this.getRequest().getName());
> > +                     needColon       = true;
> > +             }
> > +             if (this.getResponse() != null) {
> > +                     if (needColon) {
> > +                             stringBuilder.append(':');
> > +                     }
> > +                     stringBuilder.append(this.getResponse().getName());
> > +                     needColon       = true;
> > +             }
> > +             return stringBuilder.toString();
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestEngine.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestEngine.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestEngine.java
> > new file mode 100755
> > index 0000000..822006a
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestEngine.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) 2013 AT&T Knowledge Ventures
> > + *              Unpublished and Not for Publication
> > + *                     All Rights Reserved
> > + */
> > +package com.att.research.xacmlatt.pdp.test.conformance;
> > +
> > +import org.apache.commons.logging.Log;
> > +import org.apache.commons.logging.LogFactory;
> > +
> > +import com.att.research.xacml.api.Request;
> > +import com.att.research.xacml.api.Response;
> > +import com.att.research.xacml.api.pdp.PDPEngine;
> > +import com.att.research.xacml.api.pdp.PDPEngineFactory;
> > +import com.att.research.xacml.api.pdp.ScopeResolver;
> > +import com.att.research.xacml.std.dom.DOMProperties;
> > +import com.att.research.xacml.std.dom.DOMRequest;
> > +import com.att.research.xacml.std.dom.DOMResponse;
> > +import com.att.research.xacml.util.FactoryException;
> > +
> > +/**
> > + * ConformanceTestEngine handles the creation of the PDPEngine for a
> > ConformanceTest instance.
> > + *
> > + * @author car
> > + * @version $Revision: 1.2 $
> > + */
> > +public class ConformanceTestEngine {
> > +     private Log logger      =
> > LogFactory.getLog(ConformanceTestEngine.class);
> > +
> > +     private PDPEngineFactory pdpEngineFactory;
> > +     private ScopeResolver scopeResolver;
> > +     private boolean lenientRequests;
> > +     private boolean lenientPolicies;
> > +     private int iterations                  = 1;
> > +
> > +     // total of all first calls to decide()
> > +     private long firstDecideTime;
> > +     private int numberOfFirstDecides = 0;
> > +
> > +     // total of all non-first-calls to decide()
> > +     private long decideTimeMultiple;
> > +
> > +     // total of average time each test case uses for a Request
> > +     // (sum of : for each test case, average of all non-first-call
> > calls to decide() )
> > +     private long avgDecideTimeMultiple = 0;
> > +
> > +     protected PDPEngineFactory getPDPEngineFactory() throws
> > FactoryException {
> > +             if (this.pdpEngineFactory == null) {
> > +                     this.pdpEngineFactory   =
> > PDPEngineFactory.newInstance();
> > +
> >       this.pdpEngineFactory.setScopeResolver(this.scopeResolver);
> > +             }
> > +             return this.pdpEngineFactory;
> > +     }
> > +
> > +     public ConformanceTestEngine(ScopeResolver scopeResolverIn,
> > boolean lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn)
> > {
> > +             this.scopeResolver              = scopeResolverIn;
> > +             this.lenientRequests    = lenientRequestsIn;
> > +             this.lenientPolicies    = lenientPoliciesIn;
> > +             this.iterations                 = iterationsIn;
> > +     }
> > +
> > +     public ConformanceTestResult run(ConformanceTest conformanceTest)
> > {
> > +             if (conformanceTest.getRequest() == null ||
> > conformanceTest.getResponse() == null ||
> > conformanceTest.getRepository() == null) {
> > +                     logger.error("Incomplete Conformance Test: " +
> > conformanceTest.getTestName());
> > +             }
> > +             PDPEngineFactory thisPDPEngineFactory   = null;
> > +             try {
> > +                     thisPDPEngineFactory    =
> this.getPDPEngineFactory();
> > +             } catch (FactoryException ex) {
> > +                     return new ConformanceTestResult(conformanceTest,
> > ex);
> > +             }
> > +
> > +             ConformanceTestResult conformanceTestResult     = new
> > ConformanceTestResult(conformanceTest, iterations);
> > +
> > +             /*
> > +              * Load the request
> > +              */
> > +             Request request                 = null;
> > +             boolean isLenient               =
> DOMProperties.isLenient();
> > +             try {
> > +                     DOMProperties.setLenient(this.lenientRequests);
> > +                     try {
> > +                             request         =
> > DOMRequest.load(conformanceTest.getRequest());
> > +                             conformanceTestResult.setRequest(request);
> > +                     } catch (Exception ex) {
> > +                             logger.error("Exception loading Request
> file "
> > + conformanceTest.getRequest().getAbsolutePath(), ex);
> > +                             conformanceTestResult.setError(ex);
> > +                             return conformanceTestResult;
> > +
> > +                     }
> > +
> > +                     /*
> > +                      * Load the expected response
> > +                      */
> > +                     Response response               = null;
> > +                     try {
> > +                             response        =
> > DOMResponse.load(conformanceTest.getResponse());
> > +
> >       conformanceTestResult.setExpectedResponse(response);
> > +                     } catch (Exception ex) {
> > +                             logger.error("Exception loading Response
> file "
> > + conformanceTest.getResponse().getAbsolutePath(), ex);
> > +                             conformanceTestResult.setError(ex);
> > +                             return conformanceTestResult;
> > +                     }
> > +
> > +                     /*
> > +                      * Set up the configuration for the policy finder
> > +                      */
> > +
>  conformanceTest.getRepository().setXACMLProperties();
> > +                     DOMProperties.setLenient(this.lenientPolicies);
> > +
> > +                     /*
> > +                      * Create the engine
> > +                      */
> > +                     PDPEngine pdpEngine             = null;
> > +                     try {
> > +                             // pdpEngine    =
> > thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(),
> > conformanceTest.getReferencedPolicies(), pipFinderEngine);
> > +                             pdpEngine               =
> > thisPDPEngineFactory.newEngine();
> > +                     } catch (Exception ex) {
> > +                             logger.error("Exception getting PDP engine
> > instance", ex);
> > +                             conformanceTestResult.setError(ex);
> > +                             return conformanceTestResult;
> > +                     }
> > +                     if (pdpEngine == null) {
> > +                             logger.error("Null PDP engine");
> > +                             conformanceTestResult.setError(new
> > NullPointerException("Null engine"));
> > +                             return conformanceTestResult;
> > +                     }
> > +
> > +                     /*
> > +                      * Run the request
> > +                      */
> > +                     long startTime, endTime;
> > +                     long curDecideTime      = this.firstDecideTime;
> > +                     try {
> > +                             startTime       = System.nanoTime();
> > +                             response        =
> pdpEngine.decide(request);
> > +                             endTime = System.nanoTime();
> > +//System.out.println(endTime  - startTime);
> > +                             // add to total
> > +                             this.firstDecideTime    += endTime -
> startTime;
> > +                             this.numberOfFirstDecides++;
> > +                             // remember just this test
> > +
>  conformanceTestResult.setFirstCallTime(endTime
> > - startTime);
> > +
> >       conformanceTestResult.setActualResponse(response);
> > +                     } catch (Exception ex) {
> > +                             logger.error("Exception in decide", ex);
> > +                             conformanceTestResult.setError(ex);
> > +                             return conformanceTestResult;
> > +                     }
> > +                     if (response == null) {
> > +                             logger.error("Null Response");
> > +                             conformanceTestResult.setError(new
> > NullPointerException("Null Response"));
> > +                             return conformanceTestResult;
> > +                     }
> > +
> > +                     long localLoopTime = 0;
> > +                     try {
> > +                             // if user requested non-first-call calls
> to
> > decide() to get performance info, run them now.
> > +                             // We can ignore the result since we are
> only
> > interested in how long they take to process the Request.
> > +                             for (int i = 0 ; i < this.iterations ;
> i++) {
> > +                                     startTime       =
> System.nanoTime();
> > +                                     pdpEngine.decide(request);
> > +                                     endTime = System.nanoTime();
> > +//System.out.println(endTime - startTime);
> >
> > +                                     // add to the global total for all
> tests
> > +                                     this.decideTimeMultiple +=
> (endTime -
> > startTime);
> > +                                     // remember just this one test's
> info
> > +                                     localLoopTime += (endTime -
> startTime);
> > +                             }
> > +                     } catch (Exception ex) {
> > +                             logger.error("Exception in iterated
> decide",
> > ex);
> > +                             return conformanceTestResult;
> > +                     }
> > +
> > +                     // add to total average for non-first-call times
> for
> > all test cases
> > +                     avgDecideTimeMultiple += (localLoopTime /
> > iterations);
> > +//System.out.println("localLoop="+localLoopTime + "   it="+iterations
> > + "   avg=" + (localLoopTime / iterations) );
> > +                     // remember average time for just this test
> > +
> >       conformanceTestResult.setAverageTotalLoopTime(localLoopTime/itera
> > tions);
> > +
> > +                     long elapsedDecideTime  = this.firstDecideTime -
> > curDecideTime;
> > +                     logger.info("Decide Time: " + elapsedDecideTime +
> > "ns");
> > +
> > +                     return conformanceTestResult;
> > +             } finally {
> > +                     DOMProperties.setLenient(isLenient);
> > +             }
> > +     }
> > +
> > +     public long getFirstDecideTime() {
> > +             return this.firstDecideTime;
> > +     }
> > +
> > +     public long getDecideTimeMultiple() {
> > +             return this.decideTimeMultiple;
> > +     }
> > +
> > +
> > +     public long getAvgFirstDecideTime() {
> > +             return this.firstDecideTime / numberOfFirstDecides;
> > +     }
> > +     public long getAvgDecideTimeMultiple() {
> > +             return this.avgDecideTimeMultiple / numberOfFirstDecides;
> > +     }
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestResult.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestResult.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestResult.java
> > new file mode 100755
> > index 0000000..9c895c6
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestResult.java
> > @@ -0,0 +1,113 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.conformance;
> > +
> > +import com.att.research.xacml.api.Request;
> > +import com.att.research.xacml.api.Response;
> > +
> > +/**
> > + * ConformanceTestResult holds all of the objects for a single
> > conformance test run.
> > + *
> > + * @author car
> > + * @version $Revision: 1.1 $
> > + */
> > +public class ConformanceTestResult {
> > +     private ConformanceTest         conformanceTest;
> > +     private Request                         request;
> > +     private Response                        expectedResponse;
> > +     private Response                        actualResponse;
> > +     private ResponseMatchResult     responseMatchResult;
> > +     private Exception                       error;
> > +
> > +     // performance timings
> > +     private long                    firstCallTime;
> > +     private long                    averageTotalLoopTime;
> > +
> > +     // how many non-first-call times the decide() was called
> > +     private int iterations;
> > +
> > +     public ConformanceTestResult(ConformanceTest conformanceTestIn,
> > int iterations) {
> > +             this.conformanceTest    = conformanceTestIn;
> > +             this.iterations = iterations;
> > +     }
> > +
> > +     public ConformanceTestResult(ConformanceTest conformanceTestIn,
> > Exception errorIn) {
> > +             this.conformanceTest    = conformanceTestIn;
> > +             this.error                              = errorIn;
> > +     }
> > +
> > +     public int getIterations() {
> > +             return this.iterations;
> > +     }
> > +
> > +     public ConformanceTest getConformanceTest() {
> > +             return this.conformanceTest;
> > +     }
> > +     public void setConformanceTest(ConformanceTest conformanceTestIn)
> > {
> > +             this.conformanceTest    = conformanceTestIn;
> > +     }
> > +
> > +     public Request getRequest() {
> > +             return this.request;
> > +     }
> > +     public void setRequest(Request requestIn) {
> > +             this.request    = requestIn;
> > +     }
> > +
> > +     public Response getExpectedResponse() {
> > +             return this.expectedResponse;
> > +     }
> > +     public void setExpectedResponse(Response response) {
> > +             this.expectedResponse           = response;
> > +             this.responseMatchResult        = null;
> > +     }
> > +
> > +     public Response getActualResponse() {
> > +             return this.actualResponse;
> > +     }
> > +     public void setActualResponse(Response response) {
> > +             this.actualResponse             = response;
> > +             this.responseMatchResult        = null;
> > +     }
> > +
> > +     public ResponseMatchResult getResponseMatchResult() {
> > +             if (this.responseMatchResult == null &&
> > (this.actualResponse != null && this.expectedResponse != null)) {
> > +                     this.computeResponseMatchResult();
> > +             }
> > +             return this.responseMatchResult;
> > +     }
> > +     public void computeResponseMatchResult() {
> > +             if (this.expectedResponse != null && this.actualResponse !=
> > null) {
> > +                     this.responseMatchResult        =
> > ResponseMatchResult.newInstance(this.expectedResponse,
> > this.actualResponse);
> > +             }
> > +     }
> > +     public Exception getError() {
> > +             return this.error;
> > +     }
> > +     public void setError(Exception ex) {
> > +             this.error      = ex;
> > +     }
> > +
> > +     public long getFirstCallTime() {
> > +             return firstCallTime;
> > +     }
> > +     public void setFirstCallTime(long t) {
> > +             firstCallTime = t;
> > +     }
> > +     public long getAverageTotalLoopTime(){
> > +             return averageTotalLoopTime;
> > +     }
> > +     public void setAverageTotalLoopTime(long t) {
> > +             averageTotalLoopTime = t;
> > +     }
> > +
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestSet.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestSet.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestSet.java
> > new file mode 100755
> > index 0000000..a04b50c
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> > rmanceTestSet.java
> > @@ -0,0 +1,171 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.conformance;
> > +
> > +import java.io.File;
> > +import java.io.IOException;
> > +import java.nio.file.FileVisitResult;
> > +import java.nio.file.FileVisitor;
> > +import java.nio.file.Files;
> > +import java.nio.file.Path;
> > +import java.nio.file.attribute.BasicFileAttributes;
> > +import java.util.ArrayList;
> > +import java.util.Collections;
> > +import java.util.HashMap;
> > +import java.util.Iterator;
> > +import java.util.List;
> > +import java.util.Map;
> > +
> > +import org.apache.commons.logging.Log;
> > +import org.apache.commons.logging.LogFactory;
> > +
> > +/**
> > + * ConformanceTestSet represents a collection of
> > <code>ConformanceTest</code>s ordered by the test name.  It has methods
> > for
> > + * scanning a directory to generate an ordered set.
> > + *
> > + * @author car
> > + * @version $Revision: 1.1 $
> > + */
> > +public class ConformanceTestSet {
> > +     private static final Log logger
> >       = LogFactory.getLog(ConformanceTestSet.class);
> > +     private List<ConformanceTest> listConformanceTests      = new
> > ArrayList<ConformanceTest>();
> > +
> > +     protected List<ConformanceTest> getListConformanceTests() {
> > +             return this.listConformanceTests;
> > +     }
> > +
> > +     protected ConformanceTestSet() {
> > +
> > +     }
> > +
> > +     private static String getTestName(String fileName, int itemPos) {
> > +             return (itemPos == 0 ? "NULL" : fileName.substring(0,
> > itemPos));
> > +     }
> > +
> > +     private static String getTestName(File file) {
> > +             String fileName = file.getName();
> > +             int itemPos             = fileName.indexOf("Policy");
> > +             if (itemPos >= 0) {
> > +                     return getTestName(fileName, itemPos);
> > +             } else if ((itemPos = fileName.indexOf("Request")) >= 0) {
> > +                     return getTestName(fileName, itemPos);
> > +             } else if ((itemPos = fileName.indexOf("Response")) >= 0) {
> > +                     return getTestName(fileName, itemPos);
> > +             } else if ((itemPos = fileName.indexOf("Repository")) >= 0)
> > {
> > +                     return getTestName(fileName, itemPos);
> > +             } else {
> > +                     return null;
> > +             }
> > +     }
> > +
> > +     public static ConformanceTestSet loadDirectory(File fileDir)
> > throws IOException {
> > +             final Map<String,ConformanceTest> mapConformanceTests   =
> new
> > HashMap<String,ConformanceTest>();
> > +
> > +             Files.walkFileTree(fileDir.toPath(), new
> > FileVisitor<Path>() {
> > +                     @Override
> > +                     public FileVisitResult preVisitDirectory(Path dir,
> > BasicFileAttributes attrs) throws IOException {
> > +                             logger.info("Scanning directory " +
> > dir.getFileName());
> > +                             return FileVisitResult.CONTINUE;
> > +                     }
> > +
> > +                     @Override
> > +                     public FileVisitResult visitFile(Path file,
> > BasicFileAttributes attrs) throws IOException {
> > +                             File fileVisited        = file.toFile();
> > +                             String fileName         =
> > fileVisited.getName();
> > +                             if (fileName.endsWith(".xml") ||
> > fileName.endsWith(".properties")) {
> > +                                     String testName =
> > getTestName(fileVisited);
> > +                                     if (testName != null) {
> > +                                             ConformanceTest
> conformanceTest
> >       = mapConformanceTests.get(testName);
> > +                                             if (conformanceTest ==
> null) {
> > +                                                     logger.info("Added
> test " +
> > testName);
> > +                                                     conformanceTest =
> new
> > ConformanceTest(testName);
> > +
> >       mapConformanceTests.put(testName, conformanceTest);
> > +                                             }
> > +                                             if
> > (fileName.endsWith("Policy.xml")) {
> > +
> >       conformanceTest.getRepository().addRootPolicy(fileVisited);
> > +                                             } else if
> > (fileName.endsWith("Repository.properties")) {
> > +
> >       conformanceTest.getRepository().load(fileVisited);
> > +                                             } else if
> > (fileName.endsWith("Request.xml")) {
> > +
> >       conformanceTest.setRequest(fileVisited);
> > +                                             } else if
> > (fileName.endsWith("Response.xml")) {
> > +
> >       conformanceTest.setResponse(fileVisited);
> > +                                             }
> > +                                     }
> > +                             }
> > +                             return FileVisitResult.CONTINUE;
> > +                     }
> > +
> > +                     @Override
> > +                     public FileVisitResult visitFileFailed(Path file,
> > IOException exc)      throws IOException {
> > +                             logger.warn("Skipped " +
> file.getFileName());
> > +                             return FileVisitResult.CONTINUE;
> > +                     }
> > +
> > +                     @Override
> > +                     public FileVisitResult postVisitDirectory(Path dir,
> > IOException exc) throws IOException {
> > +                             return FileVisitResult.CONTINUE;
> > +                     }
> > +             });
> > +
> > +             /*
> > +              * Sort the keyset and pull out the tests that have the
> > required components
> > +              */
> > +             List<String> listTestNames      = new ArrayList<String>();
> > +             listTestNames.addAll(mapConformanceTests.keySet());
> > +             Collections.sort(listTestNames);
> > +
> > +             ConformanceTestSet conformanceTestSet   = new
> > ConformanceTestSet();
> > +             Iterator<String> iterTestNames  =
> > listTestNames.iterator();
> > +             while (iterTestNames.hasNext()) {
> > +                     ConformanceTest conformanceTest =
> > mapConformanceTests.get(iterTestNames.next());
> > +                     if (conformanceTest.isComplete()) {
> > +
> >       conformanceTestSet.addConformanceTest(conformanceTest);
> > +                             logger.debug("Added conformance test " +
> > conformanceTest.getTestName());
> > +                     } else {
> > +                             logger.warn("Incomplete conformance test "
> +
> > conformanceTest.getTestName());
> > +                     }
> > +             }
> > +
> > +             return conformanceTestSet;
> > +
> > +     }
> > +
> > +     public Iterator<ConformanceTest> getConformanceTests() {
> > +             return this.listConformanceTests.iterator();
> > +     }
> > +
> > +     public void addConformanceTest(ConformanceTest conformanceTest) {
> > +             this.listConformanceTests.add(conformanceTest);
> > +     }
> > +
> > +     public void addConformanceTestSet(ConformanceTestSet
> > conformanceTestSet) {
> > +
> >       this.listConformanceTests.addAll(conformanceTestSet.getListConfor
> > manceTests());
> > +     }
> > +
> > +     public static void main(String[] args) {
> > +             for (String dir : args) {
> > +                     try {
> > +                             ConformanceTestSet conformanceTestSet
> >               = ConformanceTestSet.loadDirectory(new File(dir));
> > +                             Iterator<ConformanceTest>
> iterConformanceTests
> >       = conformanceTestSet.getConformanceTests();
> > +                             if (iterConformanceTests == null) {
> > +                                     System.out.println("No tests found
> in " +
> > dir);
> > +                             } else {
> > +                                     System.out.println("Tests found in
> " +
> > dir);
> > +                                     while
> (iterConformanceTests.hasNext()) {
> > +
> >       System.out.println(iterConformanceTests.next().toString());
> > +                                     }
> > +                             }
> > +                     } catch (Exception ex) {
> > +                             ex.printStackTrace(System.err);
> > +                     }
> > +             }
> > +     }
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> > nseMatchResult.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> > nseMatchResult.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> > nseMatchResult.java
> > new file mode 100755
> > index 0000000..00db0dc
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> > nseMatchResult.java
> > @@ -0,0 +1,128 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.conformance;
> > +
> > +import java.util.ArrayList;
> > +import java.util.Collection;
> > +import java.util.Iterator;
> > +import java.util.List;
> > +
> > +import com.att.research.xacml.api.Response;
> > +import com.att.research.xacml.api.Result;
> > +
> > +/**
> > + * ResponseMatchResult provides information about how a {@link
> > com.att.research.xacml.api.Response} object matches
> > + * another <code>Response</code> object.
> > + *
> > + * @author car
> > + * @version $Revision: 1.1 $
> > + */
> > +public class ResponseMatchResult {
> > +     private List<ResultMatchResult> resultMatchResults      = new
> > ArrayList<ResultMatchResult>();
> > +
> > +     private boolean bAssociatedAdviceMatches                        =
> true;
> > +     private boolean bAttributesMatch
>       =
> > true;
> > +     private boolean bDecisionsMatch
> >       = true;
> > +     private boolean bStatusCodesMatch
>      =
> > true;
> > +     private boolean bObligationsMatch
>      =
> > true;
> > +     private boolean bPolicyIdentifiersMatch                         =
> > true;
> > +     private boolean bPolicySetIdentifiersMatch                      =
> > true;
> > +     private boolean bNumResultsMatch
>       =
> > true;
> > +     private boolean bUnknownFunction;
> > +
> > +     protected void addResultMatchResult(ResultMatchResult
> > resultMatchResult) {
> > +             this.resultMatchResults.add(resultMatchResult);
> > +             this.bAssociatedAdviceMatches   =
> > resultMatchResult.associatedAdviceMatches() &&
> > this.bAssociatedAdviceMatches;
> > +             this.bAttributesMatch                   =
> > resultMatchResult.attributesMatch() && this.bAttributesMatch;
> > +             this.bDecisionsMatch                    =
> > resultMatchResult.decisionsMatch() && this.bDecisionsMatch;
> > +             this.bStatusCodesMatch                  =
> > resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch;
> > +             this.bObligationsMatch                  =
> > resultMatchResult.obligationsMatch() && this.bObligationsMatch;
> > +             this.bPolicyIdentifiersMatch    =
> > resultMatchResult.policyIdentifiersMatch() &&
> > this.bPolicyIdentifiersMatch;
> > +             this.bPolicySetIdentifiersMatch =
> > resultMatchResult.policySetIdentifiersMatch() &&
> > this.bPolicySetIdentifiersMatch;
> > +             this.bUnknownFunction                   =
> > resultMatchResult.unknownFunction() || this.bUnknownFunction;
> > +     }
> > +
> > +     protected void setNumResultsMatch(boolean b) {
> > +             this.bNumResultsMatch   = b;
> > +     }
> > +
> > +     public ResponseMatchResult() {
> > +     }
> > +
> > +     public static ResponseMatchResult newInstance(Response response1,
> > Response response2) {
> > +             ResponseMatchResult responseMatchResult = new
> > ResponseMatchResult();
> > +
> > +             Collection<Result> listResultsResponse1 =
> > response1.getResults();
> > +             Collection<Result> listResultsResponse2 =
> > response2.getResults();
> > +             if (listResultsResponse1.size() == 1 &&
> > listResultsResponse2.size() == 1) {
> > +                     /*
> > +                      * Just add a single ResultMatchResult comparing
> the
> > results in the two responses
> > +                      */
> > +
> >       responseMatchResult.addResultMatchResult(ResultMatchResult.newIns
> > tance(listResultsResponse1.iterator().next(),
> > listResultsResponse2.iterator().next()));
> > +             } else {
> > +                     /*
> > +                      * Iterate over all of the results in the two
> > responses and match them
> > +                      */
> > +                     Iterator<Result> iterResponse1Results   =
> > listResultsResponse1.iterator();
> > +                     Iterator<Result> iterResponse2Results   =
> > listResultsResponse2.iterator();
> > +                     while ((iterResponse1Results != null &&
> > iterResponse1Results.hasNext()) || (iterResponse2Results != null &&
> > iterResponse2Results.hasNext())) {
> > +                             Result result1  = (iterResponse1Results !=
> > null && iterResponse1Results.hasNext() ? iterResponse1Results.next() :
> > null);
> > +                             Result result2  = (iterResponse2Results !=
> > null && iterResponse2Results.hasNext() ? iterResponse2Results.next() :
> > null);
> > +                             if ((result1 == null || result2 == null) &&
> > responseMatchResult.numResultsMatch()) {
> > +
> >       responseMatchResult.setNumResultsMatch(false);
> > +                             }
> > +
> >       responseMatchResult.addResultMatchResult(ResultMatchResult.newIns
> > tance(result1, result2));
> > +                     }
> > +             }
> > +             return responseMatchResult;
> > +     }
> > +
> > +     public Iterator<ResultMatchResult> getResultMatchResults() {
> > +             return this.resultMatchResults.iterator();
> > +     }
> > +
> > +     public boolean numResultsMatch() {
> > +             return this.bNumResultsMatch;
> > +     }
> > +
> > +     public boolean associatedAdviceMatches() {
> > +             return this.bAssociatedAdviceMatches;
> > +     }
> > +
> > +     public boolean attributesMatch() {
> > +             return this.bAttributesMatch;
> > +     }
> > +
> > +     public boolean decisionsMatch() {
> > +             return this.bDecisionsMatch;
> > +     }
> > +
> > +     public boolean obligationsMatch() {
> > +             return this.bObligationsMatch;
> > +     }
> > +
> > +     public boolean policyIdentifiersMatch() {
> > +             return this.bPolicyIdentifiersMatch;
> > +     }
> > +
> > +     public boolean policySetIdentifiersMatch() {
> > +             return this.bPolicySetIdentifiersMatch;
> > +     }
> > +
> > +     public boolean statusCodesMatch() {
> > +             return this.bStatusCodesMatch;
> > +     }
> > +
> > +     public boolean unknownFunction() {
> > +             return this.bUnknownFunction;
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> > tMatchResult.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> > tMatchResult.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> > tMatchResult.java
> > new file mode 100755
> > index 0000000..645a755
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> > tMatchResult.java
> > @@ -0,0 +1,127 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.conformance;
> > +
> > +import com.att.research.xacml.api.Result;
> > +import com.att.research.xacml.std.StdStatusCode;
> > +import com.att.research.xacml.util.ListUtil;
> > +
> > +/**
> > + * ResultMatchResult provides information about how well a {@link
> > com.att.research.xacml.api.Result} object matches
> > + * another <code>Result</code> object.
> > + *
> > + * @author car
> > + * @version $Revision: 1.1 $
> > + */
> > +public class ResultMatchResult {
> > +     private boolean bAssociatedAdviceMatches        = true;
> > +     private boolean bAttributesMatch                        = true;
> > +     private boolean bDecisionsMatch                         = true;
> > +     private boolean bObligationsMatch                       = true;
> > +     private boolean bPolicyIdentifiersMatch         = true;
> > +     private boolean bPolicySetIdentifiersMatch      = true;
> > +     private boolean bStatusCodesMatch                       = true;
> > +     private boolean bUnknownFunction                        = false;
> > +
> > +     protected void setAssociatedAdviceMatches(boolean b) {
> > +             this.bAssociatedAdviceMatches   = b;
> > +     }
> > +     protected void setAttributesMatch(boolean b) {
> > +             this.bAttributesMatch   = b;
> > +     }
> > +     protected void setDecisionsMatch(boolean b) {
> > +             this.bDecisionsMatch    = b;
> > +     }
> > +     protected void setObligationsMatch(boolean b) {
> > +             this.bObligationsMatch  = b;
> > +     }
> > +     protected void setPolicyIdentifiersMatch(boolean b) {
> > +             this.bPolicyIdentifiersMatch    = b;
> > +     }
> > +     protected void setPolicySetIdentifiersMatch(boolean b) {
> > +             this.bPolicySetIdentifiersMatch = b;
> > +     }
> > +     protected void setStatusCodesMatch(boolean b) {
> > +             this.bStatusCodesMatch  = b;
> > +     }
> > +     protected void setUnknownFunction(boolean b) {
> > +             this.bUnknownFunction   = b;
> > +     }
> > +
> > +     public ResultMatchResult() {
> > +     }
> > +
> > +     public static ResultMatchResult newInstance(Result result1,
> > Result result2) {
> > +             ResultMatchResult resultMatchResult     = new
> > ResultMatchResult();
> > +             if (result2 != null && result2.getStatus() != null &&
> > +
> >       result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_C
> > ODE_PROCESSING_ERROR) &&
> > +                     result2.getStatus().getStatusMessage() != null &&
> > +
> >       result2.getStatus().getStatusMessage().contains("Unknown
> > Function")
> > +                     ) {
> > +                     resultMatchResult.setUnknownFunction(true);
> > +             }
> > +             if (result1 == null || result2 == null) {
> > +
>  resultMatchResult.setAssociatedAdviceMatches(false);
> > +                     resultMatchResult.setAttributesMatch(false);
> > +                     resultMatchResult.setDecisionsMatch(false);
> > +                     resultMatchResult.setObligationsMatch(false);
> > +                     resultMatchResult.setPolicyIdentifiersMatch(false);
> > +
> >       resultMatchResult.setPolicySetIdentifiersMatch(false);
> > +                     resultMatchResult.setStatusCodesMatch(false);
> > +             } else {
> > +
> >       resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllow
> > Nulls(result1.getAssociatedAdvice(), result2.getAssociatedAdvice()));
> > +
> >       resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(re
> > sult1.getAttributes(), result2.getAttributes()));
> > +
> >       resultMatchResult.setDecisionsMatch(result1.getDecision() ==
> > result2.getDecision());
> > +
> >       resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(r
> > esult1.getObligations(), result2.getObligations()));
> > +
> >       resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowN
> > ulls(result1.getPolicyIdentifiers(), result2.getPolicyIdentifiers()));
> > +
> >       resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAll
> > owNulls(result1.getPolicySetIdentifiers(),
> > result2.getPolicySetIdentifiers()));
> > +                     if (result1.getStatus() == null ||
> > result1.getStatus().getStatusCode() == null || result2.getStatus() ==
> > null || result2.getStatus().getStatusCode() == null) {
> > +
>  resultMatchResult.setStatusCodesMatch(false);
> > +                     } else {
> > +
> >       resultMatchResult.setStatusCodesMatch(result1.getStatus().getStat
> > usCode().equals(result2.getStatus().getStatusCode()));
> > +                     }
> > +             }
> > +             return resultMatchResult;
> > +     }
> > +
> > +     public boolean associatedAdviceMatches() {
> > +             return this.bAssociatedAdviceMatches;
> > +     }
> > +
> > +     public boolean attributesMatch() {
> > +             return this.bAttributesMatch;
> > +     }
> > +
> > +     public boolean decisionsMatch() {
> > +             return this.bDecisionsMatch;
> > +     }
> > +
> > +     public boolean obligationsMatch() {
> > +             return this.bObligationsMatch;
> > +     }
> > +
> > +     public boolean policyIdentifiersMatch() {
> > +             return this.bPolicyIdentifiersMatch;
> > +     }
> > +
> > +     public boolean policySetIdentifiersMatch() {
> > +             return this.bPolicySetIdentifiersMatch;
> > +     }
> > +
> > +     public boolean statusCodesMatch() {
> > +             return this.bStatusCodesMatch;
> > +     }
> > +
> > +     public boolean unknownFunction() {
> > +             return this.bUnknownFunction;
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> > TypeFactory.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> > TypeFactory.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> > TypeFactory.java
> > new file mode 100755
> > index 0000000..b3e6cc4
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> > TypeFactory.java
> > @@ -0,0 +1,78 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.util.HashMap;
> > +import java.util.Map;
> > +
> > +import com.att.research.xacml.api.DataType;
> > +import com.att.research.xacml.api.DataTypeFactory;
> > +import com.att.research.xacml.api.Identifier;
> > +import com.att.research.xacml.std.datatypes.DataTypes;
> > +
> > +public class CustomDataTypeFactory extends DataTypeFactory {
> > +     private static final Map<Identifier,DataType<?>>
> > mapIdentifiersToDataTypes     = new HashMap<Identifier,DataType<?>>();
> > +     private static boolean mapNeedsInit
> >                                                       = true;
> > +
> > +     public static final DataTypePrivateKey
> >       DT_PRIVATEKEY                           =
> > DataTypePrivateKey.newInstance();
> > +     public static final DataTypePublicKey
> >       DT_PUBLICKEY                            =
> > DataTypePublicKey.newInstance();
> > +
> > +     private static void registerDataType(DataType<?> dataType) {
> > +             if (dataType != null && dataType.getId() != null) {
> > +                     mapIdentifiersToDataTypes.put(dataType.getId(),
> > dataType);
> > +             }
> > +     }
> > +
> > +     private static void initMap() {
> > +             if (mapNeedsInit) {
> > +                     synchronized(mapIdentifiersToDataTypes) {
> > +                             if (mapNeedsInit) {
> > +
>  registerDataType(DataTypes.DT_ANYURI);
> > +
> >       registerDataType(DataTypes.DT_BASE64BINARY);
> > +
>  registerDataType(DataTypes.DT_BOOLEAN);
> > +
>  registerDataType(DataTypes.DT_DATE);
> > +
>  registerDataType(DataTypes.DT_DATETIME);
> > +
> >       registerDataType(DataTypes.DT_DAYTIMEDURATION);
> > +
>  registerDataType(DataTypes.DT_DNSNAME);
> > +
>  registerDataType(DataTypes.DT_DOUBLE);
> > +
>  registerDataType(DataTypes.DT_HEXBINARY);
> > +
>  registerDataType(DataTypes.DT_INTEGER);
> > +
>  registerDataType(DataTypes.DT_IPADDRESS);
> > +
> >       registerDataType(DataTypes.DT_RFC822NAME);
> > +
>  registerDataType(DataTypes.DT_STRING);
> > +
>  registerDataType(DataTypes.DT_TIME);
> > +
>  registerDataType(DataTypes.DT_X500NAME);
> > +
> >       registerDataType(DataTypes.DT_XPATHEXPRESSION);
> > +
> >       registerDataType(DataTypes.DT_YEARMONTHDURATION);
> > +                                     //
> > +                                     // These are the custom data types!
> > +                                     //
> > +                                     registerDataType(DT_PRIVATEKEY);
> > +                                     registerDataType(DT_PUBLICKEY);
> > +                                     //
> > +                                     // Done
> > +                                     //
> > +                                     mapNeedsInit    = false;
> > +                             }
> > +                     }
> > +             }
> > +     }
> > +
> > +     public CustomDataTypeFactory() {
> > +             initMap();
> > +     }
> > +
> > +     @Override
> > +     public DataType<?> getDataType(Identifier dataTypeId) {
> > +             return mapIdentifiersToDataTypes.get(dataTypeId);
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> > tionDefinitionFactory.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> > tionDefinitionFactory.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> > tionDefinitionFactory.java
> > new file mode 100755
> > index 0000000..dd4decb
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> > tionDefinitionFactory.java
> > @@ -0,0 +1,80 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.lang.reflect.Field;
> > +import java.lang.reflect.Modifier;
> > +import java.security.PrivateKey;
> > +import java.security.PublicKey;
> > +import java.util.HashMap;
> > +import java.util.Map;
> > +
> > +import com.att.research.xacml.api.Identifier;
> > +import com.att.research.xacml.std.IdentifierImpl;
> > +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
> > +import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
> > +import com.att.research.xacmlatt.pdp.std.StdFunctions;
> > +import
> > com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAnd
> > Only;
> > +
> > +public class CustomFunctionDefinitionFactory extends
> > FunctionDefinitionFactory {
> > +     private static Map<Identifier,FunctionDefinition>
> >       mapFunctionDefinitions  = new
> > HashMap<Identifier,FunctionDefinition>();
> > +     private static boolean
> >       needMapInit                             = true;
> > +
> > +     public static final Identifier
> > ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY = new
> > IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:priv
> > atekey-one-and-only");
> > +     public static final Identifier ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY
> > = new
> > IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:publ
> > ickey-one-and-only");
> > +
> > +     public static final FunctionDefinition
> >       FD_PRIVATEKEY_ONE_AND_ONLY      = new
> > FunctionDefinitionBagOneAndOnly<PrivateKey>(ID_FUNCTION_PRIVATEKEY_ONE_
> > AND_ONLY, DataTypePrivateKey.newInstance());
> > +     public static final FunctionDefinition
> >       FD_PUBLICKEY_ONE_AND_ONLY       = new
> > FunctionDefinitionBagOneAndOnly<PublicKey>(ID_FUNCTION_PUBLICKEY_ONE_AN
> > D_ONLY, DataTypePublicKey.newInstance());
> > +
> > +     private static void register(FunctionDefinition
> > functionDefinition) {
> > +             mapFunctionDefinitions.put(functionDefinition.getId(),
> > functionDefinition);
> > +     }
> > +
> > +     private static void initMap() {
> > +             if (needMapInit) {
> > +                     synchronized(mapFunctionDefinitions) {
> > +                             if (needMapInit) {
> > +                                     needMapInit     = false;
> > +                                     Field[] declaredFields  =
> > StdFunctions.class.getDeclaredFields();
> > +                                     for (Field field : declaredFields)
> {
> > +                                             if
> > (Modifier.isStatic(field.getModifiers()) &&
> > +
> >       field.getName().startsWith(StdFunctions.FD_PREFIX) &&
> > +
> >       FunctionDefinition.class.isAssignableFrom(field.getType()) &&
> > +
> >       Modifier.isPublic(field.getModifiers())
> > +                                             ) {
> > +                                                     try {
> > +
> >       register((FunctionDefinition)(field.get(null)));
> > +                                                     } catch
> > (IllegalAccessException ex) {
> > +
> > +                                                     }
> > +                                             }
> > +                                     }
> > +                                     //
> > +                                     // Our custom function
> > +                                     //
> > +
> >       register(FunctionDefinitionDecrypt.newInstance());
> > +
>  register(FD_PRIVATEKEY_ONE_AND_ONLY);
> > +
>  register(FD_PUBLICKEY_ONE_AND_ONLY);
> > +                             }
> > +                     }
> > +             }
> > +     }
> > +
> > +     public CustomFunctionDefinitionFactory() {
> > +             initMap();
> > +     }
> > +
> > +     @Override
> > +     public FunctionDefinition getFunctionDefinition(Identifier
> > functionId) {
> > +             return mapFunctionDefinitions.get(functionId);
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> > ivateKey.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> > ivateKey.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> > ivateKey.java
> > new file mode 100755
> > index 0000000..4e12aef
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> > ivateKey.java
> > @@ -0,0 +1,44 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.security.PrivateKey;
> > +
> > +import com.att.research.xacml.api.DataTypeException;
> > +import com.att.research.xacml.api.Identifier;
> > +import com.att.research.xacml.std.IdentifierImpl;
> > +import com.att.research.xacml.std.datatypes.DataTypeBase;
> > +
> > +public class DataTypePrivateKey extends DataTypeBase<PrivateKey> {
> > +     public static final Identifier DT_PRIVATEKEY = new
> > IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:private");
> > +     private static final DataTypePrivateKey singleInstance = new
> > DataTypePrivateKey();
> > +
> > +     private DataTypePrivateKey() {
> > +             super(DT_PRIVATEKEY, PrivateKey.class);
> > +     }
> > +
> > +     public static DataTypePrivateKey newInstance() {
> > +             return singleInstance;
> > +     }
> > +
> > +     @Override
> > +     public PrivateKey convert(Object source) throws DataTypeException
> > {
> > +             if (source == null || (source instanceof PrivateKey) ) {
> > +                     return (PrivateKey) source;
> > +             } else if (source instanceof byte[]) {
> > +                     return (PrivateKey) source;
> > +             } else if (source instanceof String) {
> > +                     return (PrivateKey) (Object) ((String)
> > source).getBytes();
> > +             }
> > +             throw new DataTypeException(this, "Failed to convert \"" +
> > source.getClass().getCanonicalName());
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> > blicKey.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> > blicKey.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> > blicKey.java
> > new file mode 100755
> > index 0000000..d40ee82
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> > blicKey.java
> > @@ -0,0 +1,44 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.security.PublicKey;
> > +
> > +import com.att.research.xacml.api.DataTypeException;
> > +import com.att.research.xacml.api.Identifier;
> > +import com.att.research.xacml.std.IdentifierImpl;
> > +import com.att.research.xacml.std.datatypes.DataTypeBase;
> > +
> > +public class DataTypePublicKey extends DataTypeBase<PublicKey> {
> > +     public static final Identifier DT_PUBLICKEY = new
> > IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:public");
> > +     private static final DataTypePublicKey singleInstance = new
> > DataTypePublicKey();
> > +
> > +     public DataTypePublicKey() {
> > +             super(DT_PUBLICKEY, PublicKey.class);
> > +     }
> > +
> > +     public static DataTypePublicKey newInstance() {
> > +             return singleInstance;
> > +     }
> > +
> > +     @Override
> > +     public PublicKey convert(Object source) throws DataTypeException
> > {
> > +             if (source == null || (source instanceof PublicKey) ) {
> > +                     return (PublicKey) source;
> > +             } else if (source instanceof byte[]) {
> > +                     return (PublicKey) source;
> > +             } else if (source instanceof String) {
> > +                     return (PublicKey) (Object) ((String)
> > source).getBytes();
> > +             }
> > +             throw new DataTypeException(this, "Failed to convert \"" +
> > source.getClass().getCanonicalName());
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> > finitionDecrypt.java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> > finitionDecrypt.java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> > finitionDecrypt.java
> > new file mode 100755
> > index 0000000..d51c73d
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> > finitionDecrypt.java
> > @@ -0,0 +1,152 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.security.InvalidKeyException;
> > +import java.security.NoSuchAlgorithmException;
> > +import java.security.PrivateKey;
> > +import java.security.PublicKey;
> > +import java.util.List;
> > +
> > +import javax.crypto.BadPaddingException;
> > +import javax.crypto.Cipher;
> > +import javax.crypto.IllegalBlockSizeException;
> > +import javax.crypto.NoSuchPaddingException;
> > +
> > +import com.att.research.xacml.api.DataType;
> > +import com.att.research.xacml.api.DataTypeException;
> > +import com.att.research.xacml.api.Identifier;
> > +import com.att.research.xacml.api.XACML3;
> > +import com.att.research.xacml.std.IdentifierImpl;
> > +import com.att.research.xacml.std.StdStatus;
> > +import com.att.research.xacml.std.StdStatusCode;
> > +import com.att.research.xacml.std.datatypes.DataTypeHexBinary;
> > +import com.att.research.xacml.std.datatypes.DataTypeString;
> > +import com.att.research.xacml.std.datatypes.HexBinary;
> > +import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
> > +import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
> > +import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
> > +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
> > +import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
> > +
> > +public class FunctionDefinitionDecrypt implements FunctionDefinition {
> > +     public static final Identifier FD_RSA_DECRYPT = new
> > IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decr
> > ypt");
> > +     private static final FunctionDefinitionDecrypt singleInstance =
> > new FunctionDefinitionDecrypt();
> > +
> > +     public static FunctionDefinitionDecrypt newInstance() {
> > +             return singleInstance;
> > +     }
> > +
> > +     @Override
> > +     public Identifier getId() {
> > +             return FD_RSA_DECRYPT;
> > +     }
> > +
> > +     @Override
> > +     public Identifier getDataTypeId() {
> > +             return XACML3.ID_DATATYPE_STRING;
> > +     }
> > +
> > +     @Override
> > +     public boolean returnsBag() {
> > +             return false;
> > +     }
> > +
> > +     @Override
> > +     public ExpressionResult evaluate(EvaluationContext
> > evaluationContext, List<FunctionArgument> arguments) {
> > +             if (arguments == null || arguments.size() < 2) {
> > +                     return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > expecting 2 arguments."));
> > +             }
> > +             //
> > +             // What is the first argument?
> > +             //
> > +             FunctionArgument arg0 = arguments.get(0);
> > +             if (arg0.isBag()) {
> > +                     //
> > +                     // We don't support bags right now
> > +                     //
> > +                     return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > not expecting a bag for argument 0."));
> > +             }
> > +             if
> > (arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY)
> > == false) {
> > +                     //
> > +                     // Should be a String
> > +                     //
> > +                     return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > expected a Hex Binary for argument 0."));
> > +             }
> > +             //
> > +             // Convert the argument
> > +             //
> > +             ConvertedArgument<HexBinary> data = new
> > ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(),
> > false);
> > +             if (! data.isOk()) {
> > +                     return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > argument 0 failed to convert to Hex Binary."));
> > +             }
> > +             //
> > +             // Ok - check the 2nd argument
> > +             //
> > +             FunctionArgument arg1 = arguments.get(1);
> > +             if (arg1.isBag()) {
> > +                     //
> > +                     // We don't support bags right now
> > +                     //
> > +                     return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > not expecting a bag for argument 1."));
> > +             }
> > +             if
> > (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKE
> > Y) ||
> > +
> >       arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLI
> > CKEY)) {
> > +                     //
> > +                     // Ok - let's try to decrypt
> > +                     //
> > +                     Cipher cipher;
> > +                     try {
> > +                             cipher = Cipher.getInstance("RSA");
> > +                             if
> > (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKE
> > Y)) {
> > +                                     //
> > +                                     // Using the private key
> > +                                     //
> > +                                     DataType<PrivateKey> pkDatatype =
> > DataTypePrivateKey.newInstance();
> > +                                     ConvertedArgument<PrivateKey>
> privateKey
> > = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
> > +                                     if ( ! privateKey.isOk()) {
> > +                                             return
> > ExpressionResult.newError(new
> > StdStatus(privateKey.getStatus().getStatusCode(), "Decrypt: " +
> > privateKey.getStatus().getStatusMessage()));
> > +                                     }
> > +                                     //
> > +                                     // Setup decryption
> > +                                     //
> > +                                     cipher.init(Cipher.DECRYPT_MODE,
> > privateKey.getValue());
> > +                             } else if
> > (arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)
> > ) {
> > +                                     //
> > +                                     // Using the private key
> > +                                     //
> > +                                     DataType<PublicKey> pkDatatype =
> > DataTypePublicKey.newInstance();
> > +                                     ConvertedArgument<PublicKey>
> publicKey =
> > new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
> > +                                     if ( ! publicKey.isOk()) {
> > +                                             return
> > ExpressionResult.newError(new
> > StdStatus(publicKey.getStatus().getStatusCode(), "Decrypt: " +
> > publicKey.getStatus().getStatusMessage()));
> > +                                     }
> > +                                     //
> > +                                     // Setup decryption
> > +                                     //
> > +                                     cipher.init(Cipher.DECRYPT_MODE,
> > publicKey.getValue());
> > +                             }
> > +                             //
> > +                             // Do the decryption
> > +                             //
> > +                             byte[] decryptedData =
> > cipher.doFinal(data.getValue().getData());
> > +                             String decryptedString = new
> > String(decryptedData);
> > +                             //
> > +                             // All good, return the decrypted string
> > +                             //
> > +                             return
> > ExpressionResult.newSingle(DataTypeString.newInstance().createAttribute
> > Value(decryptedString));
> > +                     } catch (NoSuchAlgorithmException |
> > NoSuchPaddingException | InvalidKeyException |
> > IllegalBlockSizeException | BadPaddingException | DataTypeException e)
> > {
> > +                             return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed:
> > " + e.getLocalizedMessage()));
> > +                     }
> > +             }
> > +             return ExpressionResult.newError(new
> > StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> > expecting public/private key datatype for argument 1."));
> > +     }
> > +
> > +}
> >
> > http://git-wip-us.apache.org/repos/asf/incubator-
> > openaz/blob/94fcdd90/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> > .java
> > ----------------------------------------------------------------------
> > diff --git a/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> > .java b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> > .java
> > new file mode 100755
> > index 0000000..df93001
> > --- /dev/null
> > +++ b/openaz-xacml-
> > test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> > .java
> > @@ -0,0 +1,384 @@
> > +/*
> > + *                        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.xacmlatt.pdp.test.custom;
> > +
> > +import java.io.IOException;
> > +import java.io.ObjectInputStream;
> > +import java.io.ObjectOutputStream;
> > +import java.net.MalformedURLException;
> > +import java.nio.file.Files;
> > +import java.nio.file.Path;
> > +import java.nio.file.Paths;
> > +import java.security.InvalidKeyException;
> > +import java.security.KeyPair;
> > +import java.security.KeyPairGenerator;
> > +import java.security.NoSuchAlgorithmException;
> > +import java.security.PrivateKey;
> > +import java.security.PublicKey;
> > +import java.util.ArrayList;
> > +import java.util.List;
> > +
> > +import javax.crypto.BadPaddingException;
> > +import javax.crypto.Cipher;
> > +import javax.crypto.IllegalBlockSizeException;
> > +import javax.crypto.NoSuchPaddingException;
> > +
> > +import org.apache.commons.cli.CommandLine;
> > +import org.apache.commons.cli.GnuParser;
> > +import org.apache.commons.cli.Option;
> > +import org.apache.commons.cli.ParseException;
> > +import org.apache.commons.logging.Log;
> > +import org.apache.commons.logging.LogFactory;
> > +
> > +import com.att.research.xacml.api.AttributeValue;
> > +import com.att.research.xacml.api.DataType;
> > +import com.att.research.xacml.api.DataTypeException;
> > +import com.att.research.xacml.api.Request;
> > +import com.att.research.xacml.api.RequestAttributes;
> > +import com.att.research.xacml.api.XACML3;
> > +import com.att.research.xacml.api.pep.PEPException;
> > +import com.att.research.xacml.std.IdentifierImpl;
> > +import com.att.research.xacml.std.StdMutableAttribute;
> > +import com.att.research.xacml.std.StdMutableRequest;
> > +import com.att.research.xacml.std.StdMutableRequestAttributes;
> > +import com.att.research.xacml.std.dom.DOMStructureException;
> > +import com.att.research.xacml.std.json.JSONStructureException;
> > +import com.att.research.xacml.util.FactoryException;
> > +import com.att.research.xacmlatt.pdp.test.TestBase;
> > +
> > +/**
> > + * TestCustom is an application that tests the extensibility and
> > configurability of the AT&T XACML API.
> > + *
> > + * It creates a custom datatype definition factory that adds in custom
> > data types for RSA
> > + * PublicKey and PrivateKey.
> > + *
> > + * It creates a custom function definition factory that adds in custom
> > decryption function for decrypting data. It
> > + * also derives and loads custom functions for the RSA public/private
> > key datatypes for the bag function: one-and-only.
> > + *
> > + * @author pameladragosh
> > + *
> > + */
> > +public class TestCustom extends TestBase {
> > +     private static final Log logger =
> > LogFactory.getLog(TestCustom.class);
> > +
> > +     //
> > +     // Our public's
> > +     //
> > +     public static final String ALGORITHM = "RSA";
> > +     public static final String PRIVATEKEY_FILE = "PrivateKey.key";
> > +     public static final String PUBLICKEY_FILE = "PublicKey.key";
> > +
> > +     public static final String DECRYPTION_INPUT_STRING = "This is the
> > SECRET value!";
> > +
> > +     public static final String DECRYPTION_INPUT_ID =
> > "com:att:research:xacml:test:custom:encrypted-data";
> > +     //
> > +     // Our keys
> > +     //
> > +     protected PublicKey publicKey = null;
> > +     protected PrivateKey privateKey = null;
> > +     //
> > +     // Our command line parameters
> > +     //
> > +     public static final String OPTION_GENERATE = "generate";
> > +
> > +     static {
> > +             options.addOption(new Option(OPTION_GENERATE, false,
> > "Generate a private/public key pair."));
> > +     }
> > +
> > +     /**
> > +      * This function generates the public/private key pair. Should
> > never have to call this again, this was
> > +      * called once to generate the keys. They were saved into the
> > testsets/custom/datatype-function sub-directory.
> > +      */
> > +     public void generateKeyPair() {
> > +             //
> > +             // Generate a RSA private/public key pair
> > +             //
> > +             KeyPairGenerator keyGen;
> > +             try {
> > +                     keyGen = KeyPairGenerator.getInstance(ALGORITHM);
> > +             } catch (NoSuchAlgorithmException e) {
> > +                     logger.error("failed to generate keypair: " + e);
> > +                     return;
> > +             }
> > +             keyGen.initialize(1024);
> > +             final KeyPair key = keyGen.generateKeyPair();
> > +             //
> > +             // Save the keys to disk
> > +             //
> > +             Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
> > +             try (ObjectOutputStream os = new
> > ObjectOutputStream(Files.newOutputStream(file))) {
> > +                     os.writeObject(key.getPrivate());
> > +             } catch (IOException e) {
> > +                     e.printStackTrace();
> > +             }
> > +             file = Paths.get(this.directory, PUBLICKEY_FILE);
> > +             try (ObjectOutputStream os = new
> > ObjectOutputStream(Files.newOutputStream(file))) {
> > +                     os.writeObject(key.getPublic());
> > +             } catch (IOException e) {
> > +                     e.printStackTrace();
> > +             }
> > +     }
> > +
> > +     public TestCustom(String[] args) throws ParseException,
> > MalformedURLException, HelpException {
> > +             super(args);
> > +     }
> > +
> > +     /* (non-Javadoc)
> > +      *
> > +      * Simply look for command line option: -generate
> > +      * This generates the public/private key. Shouldn't need to call
> > it again, the keys have
> > +      * already been generated and saved.
> > +      *
> > +      * @see
> > com.att.research.xacmlatt.pdp.test.TestBase#parseCommands(java.lang.Str
> > ing[])
> > +      */
> > +     @Override
> > +     protected void parseCommands(String[] args) throws
> > ParseException, MalformedURLException, HelpException {
> > +             //
> > +             // Have our parent class parse its options out
> > +             //
> > +             super.parseCommands(args);
> > +             //
> > +             // Parse the command line options
> > +             //
> > +             CommandLine cl;
> > +             cl = new GnuParser().parse(options, args);
> > +             if (cl.hasOption(OPTION_GENERATE)) {
> > +                     //
> > +                     // Really only need to do this once to setup the
> > test.
> > +                     //
> > +                     this.generateKeyPair();
> > +             }
> > +     }
> > +
> > +     /* (non-Javadoc)
> > +      *
> > +      * After our parent class configure's itself, all this needs to
> > do is read in
> > +      * the public/private key's into objects.
> > +      *
> > +      * @see com.att.research.xacmlatt.pdp.test.TestBase#configure()
> > +      */
> > +     @Override
> > +     protected void configure() throws FactoryException {
> > +             //
> > +             // Have our super do its thing
> > +             //
> > +             super.configure();
> > +             //
> > +             // Read in the public key
> > +             //
> > +             try {
> > +                     this.publicKey = (PublicKey) new
> > ObjectInputStream(Files.newInputStream(Paths.get(this.directory,
> > PUBLICKEY_FILE))).readObject();
> > +             } catch (ClassNotFoundException | IOException e) {
> > +                     logger.error(e);
> > +             }
> > +             //
> > +             // Read in the private key
> > +             //
> > +             try {
> > +                     this.privateKey = (PrivateKey) new
> > ObjectInputStream(Files.newInputStream(Paths.get(this.directory,
> > PRIVATEKEY_FILE))).readObject();
> > +             } catch (ClassNotFoundException | IOException e) {
> > +                     logger.error(e);
> > +             }
> > +     }
> > +
> > +     /* (non-Javadoc)
> > +      *
> > +      * Here we add 2 attributes into the request: 1) the private key,
> > and 2) a String that was encrypted using the public key.
> > +      *
> > +      * The goal is to have the custom decrypt function use the
> > private key to decrypt that string.
> > +      *
> > +      * @see
> > com.att.research.xacmlatt.pdp.test.TestBase#generateRequest(java.nio.fi
> > le.Path, java.lang.String)
> > +      */
> > +     @Override
> > +     protected Request generateRequest(Path file, String group) throws
> > JSONStructureException, DOMStructureException, PEPException {
> > +             //
> > +             // Have our super class do its work
> > +             //
> > +             Request oldRequest = super.generateRequest(file, group);
> > +             //
> > +             // Copy the request attributes
> > +             //
> > +             List<StdMutableRequestAttributes> attributes = new
> > ArrayList<StdMutableRequestAttributes>();
> > +             for (RequestAttributes a :
> > oldRequest.getRequestAttributes()) {
> > +                     attributes.add(new StdMutableRequestAttributes(a));
> > +             }
> > +             //
> > +             // We are supplying the private key as an attribute for the
> > decryption function to use:
> > +             //
> > +             // (NOTE: Ideally this would be provided by a custom PIP
> > provider, not the PEP)
> > +             //
> > +             // ID=com:att:research:xacml:test:custom:privatekey
> > +             // Issuer=com:att:research:xacml:test:custom
> > +             // Category=urn:oasis:names:tc:xacml:1.0:subject-
> > category:access-subject
> > +             //
> > Datatype=urn:com:att:research:xacml:custom:3.0:rsa:private
> > +             //
> > +             DataType<?> dtExtended =
> > dataTypeFactory.getDataType(DataTypePrivateKey.DT_PRIVATEKEY);
> > +             if (dtExtended == null) {
> > +                     logger.error("Failed to get private key
> datatype.");
> > +                     return null;
> > +             }
> > +             //
> > +             // Create the attribute value
> > +             //
> > +             try {
> > +                     AttributeValue<?> attributeValue =
> > dtExtended.createAttributeValue(this.privateKey);
> >
> > +                     //
> > +                     // Create the attribute
> > +                     //
> > +                     StdMutableAttribute newAttribute = new
> > StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
> > +
> >                                                       new
> > IdentifierImpl("com:att:research:xacml:test:custom:privatekey"),
> > +
> >                                                       attributeValue,
> > +
> >
> >       "com:att:research:xacml:test:custom",
> > +
> >                                                       false);
> > +                     boolean added = false;
> > +                     for (StdMutableRequestAttributes a : attributes) {
> > +                             //
> > +                             // Does the category exist?
> > +                             //
> > +                             if
> > (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
> > +                                     //
> > +                                     // Yes - add in the new attribute
> value
> > +                                     //
> > +                                     a.add(newAttribute);
> > +                                     added = true;
> > +                                     break;
> > +                             }
> > +                     }
> > +                     if (added == false) {
> > +                             //
> > +                             // New category - create it and add it in
> > +                             //
> > +                             StdMutableRequestAttributes a = new
> > StdMutableRequestAttributes();
> > +                             a.setCategory(newAttribute.getCategory());
> > +                             a.add(newAttribute);
> > +                             attributes.add(a);
> > +                     }
> > +             } catch (DataTypeException e) {
> > +                     logger.error(e);
> > +                     return null;
> > +             }
> > +             //
> > +             // We are also supplying this attribute which is the secret
> > text encrypted with
> > +             // the public key.
> > +             //
> > +             // ID=com:att:research:xacml:test:custom:encrypted-data
> > +             // Issuer=
> > +             // Category=urn:oasis:names:tc:xacml:1.0:subject-
> > category:access-subject
> > +             // Datatype=http://www.w3.org/2001/XMLSchema#hexBinary
> > +             //
> > +             // Encrypt it
> > +             //
> > +             byte[] encryptedData = null;
> > +             try {
> > +                     Cipher cipher = Cipher.getInstance(ALGORITHM);
> > +                     cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
> > +                     //
> > +                     // This is just a hack to test a decryption of the
> > wrong value.
> > +                     //
> > +                     if (group.equals("Permit")) {
> > +                             encryptedData =
> > cipher.doFinal(DECRYPTION_INPUT_STRING.getBytes());
> > +                     } else {
> > +                             encryptedData = cipher.doFinal("This is
> NOT the
> > secret".getBytes());
> > +                     }
> > +             } catch (NoSuchAlgorithmException | NoSuchPaddingException
> > | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
> > e) {
> > +                     logger.error(e);
> > +                     return null;
> > +             }
> > +             //
> > +             // Sanity check (for the Permit request)
> > +             //
> > +             try {
> > +                     if (group.equals("Permit")) {
> > +                             Cipher cipher =
> Cipher.getInstance(ALGORITHM);
> > +                             cipher.init(Cipher.DECRYPT_MODE,
> > this.privateKey);
> > +                             byte[] decryptedData =
> > cipher.doFinal(encryptedData);
> > +                             if (new
> > String(decryptedData).equals(DECRYPTION_INPUT_STRING)) {
> > +                                     logger.info("Sanity check passed:
> > decrypted the encrypted data.");
> > +                             } else {
> > +                                     logger.error("Sanity check failed
> to
> > decrypt the encrypted data.");
> > +                                     return null;
> > +                             }
> > +                     }
> > +             } catch (NoSuchAlgorithmException | NoSuchPaddingException
> > | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
> > e) {
> > +                     logger.error(e);
> > +             }
> > +             //
> > +             // Get our datatype factory
> > +             //
> > +             dtExtended =
> > dataTypeFactory.getDataType(XACML3.ID_DATATYPE_HEXBINARY);
> > +             if (dtExtended == null) {
> > +                     logger.error("Failed to get hex binary datatype.");
> > +                     return null;
> > +             }
> > +             //
> > +             // Create the attribute value
> > +             //
> > +             try {
> > +                     AttributeValue<?> attributeValue =
> > dtExtended.createAttributeValue(encryptedData);
> >
> > +                     //
> > +                     // Create the attribute
> > +                     //
> > +                     StdMutableAttribute newAttribute = new
> > StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
> > +
> >                                                       new
> > IdentifierImpl("com:att:research:xacml:test:custom:encrypted-data"),
> > +
> >                                                       attributeValue,
> > +
> >                                                       null,
> > +
> >                                                       false);
> > +                     boolean added = false;
> > +                     for (StdMutableRequestAttributes a : attributes) {
> > +                             //
> > +                             // Does the category exist?
> > +                             //
> > +                             if
> > (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
> > +                                     //
> > +                                     // Yes - add in the new attribute
> value
> > +                                     //
> > +                                     a.add(newAttribute);
> > +                                     added = true;
> > +                                     break;
> > +                             }
> > +                     }
> > +                     if (added == false) {
> > +                             //
> > +                             // New category - create it and add it in
> > +                             //
> > +                             StdMutableRequestAttributes a = new
> > StdMutableRequestAttributes();
> > +                             a.setCategory(newAttribute.getCategory());
> > +                             a.add(newAttribute);
> > +                             attributes.add(a);
> > +                     }
> > +             } catch (DataTypeException e) {
> > +                     logger.error(e);
> > +                     return null;
> > +             }
> > +             //
> > +             // Now form our final request
> > +             //
> > +             StdMutableRequest newRequest = new StdMutableRequest();
> > +
> >       newRequest.setCombinedDecision(oldRequest.getCombinedDecision());
> > +
> >       newRequest.setRequestDefaults(oldRequest.getRequestDefaults());
> > +
> >       newRequest.setReturnPolicyIdList(oldRequest.getReturnPolicyIdList
> > ());
> > +             newRequest.setStatus(oldRequest.getStatus());
> > +             for (StdMutableRequestAttributes a : attributes) {
> > +                     newRequest.add(a);
> > +             }
> > +             return newRequest;
> > +     }
> > +
> > +     public static void main(String[] args) {
> > +             try {
> > +                     new TestCustom(args).run();
> > +             } catch (ParseException | IOException | FactoryException e)
> > {
> > +                     logger.error(e);
> > +             } catch (HelpException e) {
> > +             }
> > +     }
> > +
> > +}
> >
>



-- 
Colm O hEigeartaigh

Talend Community Coder
http://coders.talend.com

RE: [10/51] [partial] incubator-openaz git commit: Initial seed of merged of AT&T and JP Morgan code

Posted by Hal Lockhart <ha...@oracle.com>.
I thought messages of this type would go to commits or some other list. This will make dev unusable.

Hal

> -----Original Message-----
> From: pdragosh@apache.org [mailto:pdragosh@apache.org]
> Sent: Monday, April 13, 2015 11:38 AM
> To: dev@openaz.incubator.apache.org
> Subject: [10/51] [partial] incubator-openaz git commit: Initial seed of
> merged of AT&T and JP Morgan code
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTest.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTest.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTest.java
> new file mode 100755
> index 0000000..be0b46f
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTest.java
> @@ -0,0 +1,95 @@
> +/*
> + *                        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.xacmlatt.pdp.test.conformance;
> +
> +import java.io.File;
> +
> +/**
> + * ConformanceTest represents a collection of XACML files with a root
> Policy document, optional referenced Policy documents, a Request, and a
> Response.
> + *
> + * @author car
> + * @version $Revision: 1.2 $
> + */
> +public class ConformanceTest {
> +	private String testName;
> +	private File request;
> +	private File response;
> +	private ConformanceRepository repository;
> +
> +	public ConformanceTest(String name, ConformanceRepository
> conformanceRepository, File fileRequest, File fileResponse) {
> +		this.testName	= name;
> +		this.request	= fileRequest;
> +		this.response	= fileResponse;
> +		this.repository	= conformanceRepository;
> +	}
> +
> +	public ConformanceTest(String name) {
> +		this.testName	= name;
> +	}
> +
> +	public String getTestName() {
> +		return this.testName;
> +	}
> +	public void setTestName(String s) {
> +		this.testName	= s;
> +	}
> +	public ConformanceRepository getRepository() {
> +		if (this.repository == null) {
> +			this.repository	= new ConformanceRepository();
> +		}
> +		return this.repository;
> +	}
> +	public File getRequest() {
> +		return this.request;
> +	}
> +	public void setRequest(File f) {
> +		this.request	= f;
> +	}
> +	public File getResponse() {
> +		return this.response;
> +	}
> +	public void setResponse(File f) {
> +		this.response	= f;
> +	}
> +
> +	public boolean isComplete() {
> +		return this.getTestName() != null && this.getRepository()
> != null && this.getRepository().hasRootPolicy() && this.getRequest() !=
> null && this.getResponse() != null;
> +	}
> +
> +	@Override
> +	public String toString() {
> +		StringBuilder stringBuilder	= new StringBuilder();
> +		boolean needColon			= false;
> +		if (this.getTestName() != null) {
> +			stringBuilder.append(this.getTestName());
> +			needColon	= true;
> +		}
> +		if (this.getRepository() != null) {
> +
> +		}
> +		if (this.getRequest() != null) {
> +			if (needColon) {
> +				stringBuilder.append(':');
> +			}
> +			stringBuilder.append(this.getRequest().getName());
> +			needColon	= true;
> +		}
> +		if (this.getResponse() != null) {
> +			if (needColon) {
> +				stringBuilder.append(':');
> +			}
> +			stringBuilder.append(this.getResponse().getName());
> +			needColon	= true;
> +		}
> +		return stringBuilder.toString();
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestEngine.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestEngine.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestEngine.java
> new file mode 100755
> index 0000000..822006a
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestEngine.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) 2013 AT&T Knowledge Ventures
> + *              Unpublished and Not for Publication
> + *                     All Rights Reserved
> + */
> +package com.att.research.xacmlatt.pdp.test.conformance;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +import com.att.research.xacml.api.Request;
> +import com.att.research.xacml.api.Response;
> +import com.att.research.xacml.api.pdp.PDPEngine;
> +import com.att.research.xacml.api.pdp.PDPEngineFactory;
> +import com.att.research.xacml.api.pdp.ScopeResolver;
> +import com.att.research.xacml.std.dom.DOMProperties;
> +import com.att.research.xacml.std.dom.DOMRequest;
> +import com.att.research.xacml.std.dom.DOMResponse;
> +import com.att.research.xacml.util.FactoryException;
> +
> +/**
> + * ConformanceTestEngine handles the creation of the PDPEngine for a
> ConformanceTest instance.
> + *
> + * @author car
> + * @version $Revision: 1.2 $
> + */
> +public class ConformanceTestEngine {
> +	private Log logger	=
> LogFactory.getLog(ConformanceTestEngine.class);
> +
> +	private PDPEngineFactory pdpEngineFactory;
> +	private ScopeResolver scopeResolver;
> +	private boolean lenientRequests;
> +	private boolean lenientPolicies;
> +	private int iterations			= 1;
> +
> +	// total of all first calls to decide()
> +	private long firstDecideTime;
> +	private int numberOfFirstDecides = 0;
> +
> +	// total of all non-first-calls to decide()
> +	private long decideTimeMultiple;
> +
> +	// total of average time each test case uses for a Request
> +	// (sum of : for each test case, average of all non-first-call
> calls to decide() )
> +	private long avgDecideTimeMultiple = 0;
> +
> +	protected PDPEngineFactory getPDPEngineFactory() throws
> FactoryException {
> +		if (this.pdpEngineFactory == null) {
> +			this.pdpEngineFactory	=
> PDPEngineFactory.newInstance();
> +
> 	this.pdpEngineFactory.setScopeResolver(this.scopeResolver);
> +		}
> +		return this.pdpEngineFactory;
> +	}
> +
> +	public ConformanceTestEngine(ScopeResolver scopeResolverIn,
> boolean lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn)
> {
> +		this.scopeResolver		= scopeResolverIn;
> +		this.lenientRequests	= lenientRequestsIn;
> +		this.lenientPolicies	= lenientPoliciesIn;
> +		this.iterations			= iterationsIn;
> +	}
> +
> +	public ConformanceTestResult run(ConformanceTest conformanceTest)
> {
> +		if (conformanceTest.getRequest() == null ||
> conformanceTest.getResponse() == null ||
> conformanceTest.getRepository() == null) {
> +			logger.error("Incomplete Conformance Test: " +
> conformanceTest.getTestName());
> +		}
> +		PDPEngineFactory thisPDPEngineFactory	= null;
> +		try {
> +			thisPDPEngineFactory	= this.getPDPEngineFactory();
> +		} catch (FactoryException ex) {
> +			return new ConformanceTestResult(conformanceTest,
> ex);
> +		}
> +
> +		ConformanceTestResult conformanceTestResult	= new
> ConformanceTestResult(conformanceTest, iterations);
> +
> +		/*
> +		 * Load the request
> +		 */
> +		Request request			= null;
> +		boolean isLenient		= DOMProperties.isLenient();
> +		try {
> +			DOMProperties.setLenient(this.lenientRequests);
> +			try {
> +				request		=
> DOMRequest.load(conformanceTest.getRequest());
> +				conformanceTestResult.setRequest(request);
> +			} catch (Exception ex) {
> +				logger.error("Exception loading Request file "
> + conformanceTest.getRequest().getAbsolutePath(), ex);
> +				conformanceTestResult.setError(ex);
> +				return conformanceTestResult;
> +
> +			}
> +
> +			/*
> +			 * Load the expected response
> +			 */
> +			Response response		= null;
> +			try {
> +				response	=
> DOMResponse.load(conformanceTest.getResponse());
> +
> 	conformanceTestResult.setExpectedResponse(response);
> +			} catch (Exception ex) {
> +				logger.error("Exception loading Response file "
> + conformanceTest.getResponse().getAbsolutePath(), ex);
> +				conformanceTestResult.setError(ex);
> +				return conformanceTestResult;
> +			}
> +
> +			/*
> +			 * Set up the configuration for the policy finder
> +			 */
> +			conformanceTest.getRepository().setXACMLProperties();
> +			DOMProperties.setLenient(this.lenientPolicies);
> +
> +			/*
> +			 * Create the engine
> +			 */
> +			PDPEngine pdpEngine		= null;
> +			try {
> +				// pdpEngine	=
> thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(),
> conformanceTest.getReferencedPolicies(), pipFinderEngine);
> +				pdpEngine		=
> thisPDPEngineFactory.newEngine();
> +			} catch (Exception ex) {
> +				logger.error("Exception getting PDP engine
> instance", ex);
> +				conformanceTestResult.setError(ex);
> +				return conformanceTestResult;
> +			}
> +			if (pdpEngine == null) {
> +				logger.error("Null PDP engine");
> +				conformanceTestResult.setError(new
> NullPointerException("Null engine"));
> +				return conformanceTestResult;
> +			}
> +
> +			/*
> +			 * Run the request
> +			 */
> +			long startTime, endTime;
> +			long curDecideTime	= this.firstDecideTime;
> +			try {
> +				startTime	= System.nanoTime();
> +				response	= pdpEngine.decide(request);
> +				endTime = System.nanoTime();
> +//System.out.println(endTime  - startTime);
> +				// add to total
> +				this.firstDecideTime	+= endTime - startTime;
> +				this.numberOfFirstDecides++;
> +				// remember just this test
> +				conformanceTestResult.setFirstCallTime(endTime
> - startTime);
> +
> 	conformanceTestResult.setActualResponse(response);
> +			} catch (Exception ex) {
> +				logger.error("Exception in decide", ex);
> +				conformanceTestResult.setError(ex);
> +				return conformanceTestResult;
> +			}
> +			if (response == null) {
> +				logger.error("Null Response");
> +				conformanceTestResult.setError(new
> NullPointerException("Null Response"));
> +				return conformanceTestResult;
> +			}
> +
> +			long localLoopTime = 0;
> +			try {
> +				// if user requested non-first-call calls to
> decide() to get performance info, run them now.
> +				// We can ignore the result since we are only
> interested in how long they take to process the Request.
> +				for (int i = 0 ; i < this.iterations ; i++) {
> +					startTime	= System.nanoTime();
> +					pdpEngine.decide(request);
> +					endTime = System.nanoTime();
> +//System.out.println(endTime - startTime);
> 
> +					// add to the global total for all tests
> +					this.decideTimeMultiple	+= (endTime -
> startTime);
> +					// remember just this one test's info
> +					localLoopTime += (endTime - startTime);
> +				}
> +			} catch (Exception ex) {
> +				logger.error("Exception in iterated decide",
> ex);
> +				return conformanceTestResult;
> +			}
> +
> +			// add to total average for non-first-call times for
> all test cases
> +			avgDecideTimeMultiple += (localLoopTime /
> iterations);
> +//System.out.println("localLoop="+localLoopTime + "   it="+iterations
> + "   avg=" + (localLoopTime / iterations) );
> +			// remember average time for just this test
> +
> 	conformanceTestResult.setAverageTotalLoopTime(localLoopTime/itera
> tions);
> +
> +			long elapsedDecideTime	= this.firstDecideTime -
> curDecideTime;
> +			logger.info("Decide Time: " + elapsedDecideTime +
> "ns");
> +
> +			return conformanceTestResult;
> +		} finally {
> +			DOMProperties.setLenient(isLenient);
> +		}
> +	}
> +
> +	public long getFirstDecideTime() {
> +		return this.firstDecideTime;
> +	}
> +
> +	public long getDecideTimeMultiple() {
> +		return this.decideTimeMultiple;
> +	}
> +
> +
> +	public long getAvgFirstDecideTime() {
> +		return this.firstDecideTime / numberOfFirstDecides;
> +	}
> +	public long getAvgDecideTimeMultiple() {
> +		return this.avgDecideTimeMultiple / numberOfFirstDecides;
> +	}
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestResult.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestResult.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestResult.java
> new file mode 100755
> index 0000000..9c895c6
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestResult.java
> @@ -0,0 +1,113 @@
> +/*
> + *                        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.xacmlatt.pdp.test.conformance;
> +
> +import com.att.research.xacml.api.Request;
> +import com.att.research.xacml.api.Response;
> +
> +/**
> + * ConformanceTestResult holds all of the objects for a single
> conformance test run.
> + *
> + * @author car
> + * @version $Revision: 1.1 $
> + */
> +public class ConformanceTestResult {
> +	private ConformanceTest		conformanceTest;
> +	private Request				request;
> +	private Response			expectedResponse;
> +	private Response			actualResponse;
> +	private ResponseMatchResult	responseMatchResult;
> +	private Exception			error;
> +
> +	// performance timings
> +	private long 			firstCallTime;
> +	private long 			averageTotalLoopTime;
> +
> +	// how many non-first-call times the decide() was called
> +	private int iterations;
> +
> +	public ConformanceTestResult(ConformanceTest conformanceTestIn,
> int iterations) {
> +		this.conformanceTest	= conformanceTestIn;
> +		this.iterations = iterations;
> +	}
> +
> +	public ConformanceTestResult(ConformanceTest conformanceTestIn,
> Exception errorIn) {
> +		this.conformanceTest	= conformanceTestIn;
> +		this.error				= errorIn;
> +	}
> +
> +	public int getIterations() {
> +		return this.iterations;
> +	}
> +
> +	public ConformanceTest getConformanceTest() {
> +		return this.conformanceTest;
> +	}
> +	public void setConformanceTest(ConformanceTest conformanceTestIn)
> {
> +		this.conformanceTest	= conformanceTestIn;
> +	}
> +
> +	public Request getRequest() {
> +		return this.request;
> +	}
> +	public void setRequest(Request requestIn) {
> +		this.request	= requestIn;
> +	}
> +
> +	public Response getExpectedResponse() {
> +		return this.expectedResponse;
> +	}
> +	public void setExpectedResponse(Response response) {
> +		this.expectedResponse		= response;
> +		this.responseMatchResult	= null;
> +	}
> +
> +	public Response getActualResponse() {
> +		return this.actualResponse;
> +	}
> +	public void setActualResponse(Response response) {
> +		this.actualResponse		= response;
> +		this.responseMatchResult	= null;
> +	}
> +
> +	public ResponseMatchResult getResponseMatchResult() {
> +		if (this.responseMatchResult == null &&
> (this.actualResponse != null && this.expectedResponse != null)) {
> +			this.computeResponseMatchResult();
> +		}
> +		return this.responseMatchResult;
> +	}
> +	public void computeResponseMatchResult() {
> +		if (this.expectedResponse != null && this.actualResponse !=
> null) {
> +			this.responseMatchResult	=
> ResponseMatchResult.newInstance(this.expectedResponse,
> this.actualResponse);
> +		}
> +	}
> +	public Exception getError() {
> +		return this.error;
> +	}
> +	public void setError(Exception ex) {
> +		this.error	= ex;
> +	}
> +
> +	public long getFirstCallTime() {
> +		return firstCallTime;
> +	}
> +	public void setFirstCallTime(long t) {
> +		firstCallTime = t;
> +	}
> +	public long getAverageTotalLoopTime(){
> +		return averageTotalLoopTime;
> +	}
> +	public void setAverageTotalLoopTime(long t) {
> +		averageTotalLoopTime = t;
> +	}
> +
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestSet.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestSet.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestSet.java
> new file mode 100755
> index 0000000..a04b50c
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Confo
> rmanceTestSet.java
> @@ -0,0 +1,171 @@
> +/*
> + *                        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.xacmlatt.pdp.test.conformance;
> +
> +import java.io.File;
> +import java.io.IOException;
> +import java.nio.file.FileVisitResult;
> +import java.nio.file.FileVisitor;
> +import java.nio.file.Files;
> +import java.nio.file.Path;
> +import java.nio.file.attribute.BasicFileAttributes;
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.HashMap;
> +import java.util.Iterator;
> +import java.util.List;
> +import java.util.Map;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +/**
> + * ConformanceTestSet represents a collection of
> <code>ConformanceTest</code>s ordered by the test name.  It has methods
> for
> + * scanning a directory to generate an ordered set.
> + *
> + * @author car
> + * @version $Revision: 1.1 $
> + */
> +public class ConformanceTestSet {
> +	private static final Log logger
> 	= LogFactory.getLog(ConformanceTestSet.class);
> +	private List<ConformanceTest> listConformanceTests	= new
> ArrayList<ConformanceTest>();
> +
> +	protected List<ConformanceTest> getListConformanceTests() {
> +		return this.listConformanceTests;
> +	}
> +
> +	protected ConformanceTestSet() {
> +
> +	}
> +
> +	private static String getTestName(String fileName, int itemPos) {
> +		return (itemPos == 0 ? "NULL" : fileName.substring(0,
> itemPos));
> +	}
> +
> +	private static String getTestName(File file) {
> +		String fileName	= file.getName();
> +		int itemPos		= fileName.indexOf("Policy");
> +		if (itemPos >= 0) {
> +			return getTestName(fileName, itemPos);
> +		} else if ((itemPos = fileName.indexOf("Request")) >= 0) {
> +			return getTestName(fileName, itemPos);
> +		} else if ((itemPos = fileName.indexOf("Response")) >= 0) {
> +			return getTestName(fileName, itemPos);
> +		} else if ((itemPos = fileName.indexOf("Repository")) >= 0)
> {
> +			return getTestName(fileName, itemPos);
> +		} else {
> +			return null;
> +		}
> +	}
> +
> +	public static ConformanceTestSet loadDirectory(File fileDir)
> throws IOException {
> +		final Map<String,ConformanceTest> mapConformanceTests	= new
> HashMap<String,ConformanceTest>();
> +
> +		Files.walkFileTree(fileDir.toPath(), new
> FileVisitor<Path>() {
> +			@Override
> +			public FileVisitResult preVisitDirectory(Path dir,
> BasicFileAttributes attrs) throws IOException {
> +				logger.info("Scanning directory " +
> dir.getFileName());
> +				return FileVisitResult.CONTINUE;
> +			}
> +
> +			@Override
> +			public FileVisitResult visitFile(Path file,
> BasicFileAttributes attrs) throws IOException {
> +				File fileVisited	= file.toFile();
> +				String fileName		=
> fileVisited.getName();
> +				if (fileName.endsWith(".xml") ||
> fileName.endsWith(".properties")) {
> +					String testName	=
> getTestName(fileVisited);
> +					if (testName != null) {
> +						ConformanceTest conformanceTest
> 	= mapConformanceTests.get(testName);
> +						if (conformanceTest == null) {
> +							logger.info("Added test " +
> testName);
> +							conformanceTest	= new
> ConformanceTest(testName);
> +
> 	mapConformanceTests.put(testName, conformanceTest);
> +						}
> +						if
> (fileName.endsWith("Policy.xml")) {
> +
> 	conformanceTest.getRepository().addRootPolicy(fileVisited);
> +						} else if
> (fileName.endsWith("Repository.properties")) {
> +
> 	conformanceTest.getRepository().load(fileVisited);
> +						} else if
> (fileName.endsWith("Request.xml")) {
> +
> 	conformanceTest.setRequest(fileVisited);
> +						} else if
> (fileName.endsWith("Response.xml")) {
> +
> 	conformanceTest.setResponse(fileVisited);
> +						}
> +					}
> +				}
> +				return FileVisitResult.CONTINUE;
> +			}
> +
> +			@Override
> +			public FileVisitResult visitFileFailed(Path file,
> IOException exc) 	throws IOException {
> +				logger.warn("Skipped " + file.getFileName());
> +				return FileVisitResult.CONTINUE;
> +			}
> +
> +			@Override
> +			public FileVisitResult postVisitDirectory(Path dir,
> IOException exc) throws IOException {
> +				return FileVisitResult.CONTINUE;
> +			}
> +		});
> +
> +		/*
> +		 * Sort the keyset and pull out the tests that have the
> required components
> +		 */
> +		List<String> listTestNames	= new ArrayList<String>();
> +		listTestNames.addAll(mapConformanceTests.keySet());
> +		Collections.sort(listTestNames);
> +
> +		ConformanceTestSet conformanceTestSet	= new
> ConformanceTestSet();
> +		Iterator<String> iterTestNames	=
> listTestNames.iterator();
> +		while (iterTestNames.hasNext()) {
> +			ConformanceTest	conformanceTest	=
> mapConformanceTests.get(iterTestNames.next());
> +			if (conformanceTest.isComplete()) {
> +
> 	conformanceTestSet.addConformanceTest(conformanceTest);
> +				logger.debug("Added conformance test " +
> conformanceTest.getTestName());
> +			} else {
> +				logger.warn("Incomplete conformance test " +
> conformanceTest.getTestName());
> +			}
> +		}
> +
> +		return conformanceTestSet;
> +
> +	}
> +
> +	public Iterator<ConformanceTest> getConformanceTests() {
> +		return this.listConformanceTests.iterator();
> +	}
> +
> +	public void addConformanceTest(ConformanceTest conformanceTest) {
> +		this.listConformanceTests.add(conformanceTest);
> +	}
> +
> +	public void addConformanceTestSet(ConformanceTestSet
> conformanceTestSet) {
> +
> 	this.listConformanceTests.addAll(conformanceTestSet.getListConfor
> manceTests());
> +	}
> +
> +	public static void main(String[] args) {
> +		for (String dir : args) {
> +			try {
> +				ConformanceTestSet conformanceTestSet
> 		= ConformanceTestSet.loadDirectory(new File(dir));
> +				Iterator<ConformanceTest> iterConformanceTests
> 	= conformanceTestSet.getConformanceTests();
> +				if (iterConformanceTests == null) {
> +					System.out.println("No tests found in " +
> dir);
> +				} else {
> +					System.out.println("Tests found in " +
> dir);
> +					while (iterConformanceTests.hasNext()) {
> +
> 	System.out.println(iterConformanceTests.next().toString());
> +					}
> +				}
> +			} catch (Exception ex) {
> +				ex.printStackTrace(System.err);
> +			}
> +		}
> +	}
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> nseMatchResult.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> nseMatchResult.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> nseMatchResult.java
> new file mode 100755
> index 0000000..00db0dc
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Respo
> nseMatchResult.java
> @@ -0,0 +1,128 @@
> +/*
> + *                        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.xacmlatt.pdp.test.conformance;
> +
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Iterator;
> +import java.util.List;
> +
> +import com.att.research.xacml.api.Response;
> +import com.att.research.xacml.api.Result;
> +
> +/**
> + * ResponseMatchResult provides information about how a {@link
> com.att.research.xacml.api.Response} object matches
> + * another <code>Response</code> object.
> + *
> + * @author car
> + * @version $Revision: 1.1 $
> + */
> +public class ResponseMatchResult {
> +	private List<ResultMatchResult>	resultMatchResults	= new
> ArrayList<ResultMatchResult>();
> +
> +	private boolean bAssociatedAdviceMatches			= true;
> +	private boolean bAttributesMatch					=
> true;
> +	private boolean bDecisionsMatch
> 	= true;
> +	private boolean bStatusCodesMatch					=
> true;
> +	private boolean bObligationsMatch					=
> true;
> +	private boolean bPolicyIdentifiersMatch				=
> true;
> +	private boolean bPolicySetIdentifiersMatch			=
> true;
> +	private boolean bNumResultsMatch					=
> true;
> +	private boolean bUnknownFunction;
> +
> +	protected void addResultMatchResult(ResultMatchResult
> resultMatchResult) {
> +		this.resultMatchResults.add(resultMatchResult);
> +		this.bAssociatedAdviceMatches	=
> resultMatchResult.associatedAdviceMatches() &&
> this.bAssociatedAdviceMatches;
> +		this.bAttributesMatch			=
> resultMatchResult.attributesMatch() && this.bAttributesMatch;
> +		this.bDecisionsMatch			=
> resultMatchResult.decisionsMatch() && this.bDecisionsMatch;
> +		this.bStatusCodesMatch			=
> resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch;
> +		this.bObligationsMatch			=
> resultMatchResult.obligationsMatch() && this.bObligationsMatch;
> +		this.bPolicyIdentifiersMatch	=
> resultMatchResult.policyIdentifiersMatch() &&
> this.bPolicyIdentifiersMatch;
> +		this.bPolicySetIdentifiersMatch	=
> resultMatchResult.policySetIdentifiersMatch() &&
> this.bPolicySetIdentifiersMatch;
> +		this.bUnknownFunction			=
> resultMatchResult.unknownFunction() || this.bUnknownFunction;
> +	}
> +
> +	protected void setNumResultsMatch(boolean b) {
> +		this.bNumResultsMatch	= b;
> +	}
> +
> +	public ResponseMatchResult() {
> +	}
> +
> +	public static ResponseMatchResult newInstance(Response response1,
> Response response2) {
> +		ResponseMatchResult responseMatchResult	= new
> ResponseMatchResult();
> +
> +		Collection<Result> listResultsResponse1	=
> response1.getResults();
> +		Collection<Result> listResultsResponse2	=
> response2.getResults();
> +		if (listResultsResponse1.size() == 1 &&
> listResultsResponse2.size() == 1) {
> +			/*
> +			 * Just add a single ResultMatchResult comparing the
> results in the two responses
> +			 */
> +
> 	responseMatchResult.addResultMatchResult(ResultMatchResult.newIns
> tance(listResultsResponse1.iterator().next(),
> listResultsResponse2.iterator().next()));
> +		} else {
> +			/*
> +			 * Iterate over all of the results in the two
> responses and match them
> +			 */
> +			Iterator<Result> iterResponse1Results	=
> listResultsResponse1.iterator();
> +			Iterator<Result> iterResponse2Results	=
> listResultsResponse2.iterator();
> +			while ((iterResponse1Results != null &&
> iterResponse1Results.hasNext()) || (iterResponse2Results != null &&
> iterResponse2Results.hasNext())) {
> +				Result result1	= (iterResponse1Results !=
> null && iterResponse1Results.hasNext() ? iterResponse1Results.next() :
> null);
> +				Result result2	= (iterResponse2Results !=
> null && iterResponse2Results.hasNext() ? iterResponse2Results.next() :
> null);
> +				if ((result1 == null || result2 == null) &&
> responseMatchResult.numResultsMatch()) {
> +
> 	responseMatchResult.setNumResultsMatch(false);
> +				}
> +
> 	responseMatchResult.addResultMatchResult(ResultMatchResult.newIns
> tance(result1, result2));
> +			}
> +		}
> +		return responseMatchResult;
> +	}
> +
> +	public Iterator<ResultMatchResult> getResultMatchResults() {
> +		return this.resultMatchResults.iterator();
> +	}
> +
> +	public boolean numResultsMatch() {
> +		return this.bNumResultsMatch;
> +	}
> +
> +	public boolean associatedAdviceMatches() {
> +		return this.bAssociatedAdviceMatches;
> +	}
> +
> +	public boolean attributesMatch() {
> +		return this.bAttributesMatch;
> +	}
> +
> +	public boolean decisionsMatch() {
> +		return this.bDecisionsMatch;
> +	}
> +
> +	public boolean obligationsMatch() {
> +		return this.bObligationsMatch;
> +	}
> +
> +	public boolean policyIdentifiersMatch() {
> +		return this.bPolicyIdentifiersMatch;
> +	}
> +
> +	public boolean policySetIdentifiersMatch() {
> +		return this.bPolicySetIdentifiersMatch;
> +	}
> +
> +	public boolean statusCodesMatch() {
> +		return this.bStatusCodesMatch;
> +	}
> +
> +	public boolean unknownFunction() {
> +		return this.bUnknownFunction;
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> tMatchResult.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> tMatchResult.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> tMatchResult.java
> new file mode 100755
> index 0000000..645a755
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/conformance/Resul
> tMatchResult.java
> @@ -0,0 +1,127 @@
> +/*
> + *                        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.xacmlatt.pdp.test.conformance;
> +
> +import com.att.research.xacml.api.Result;
> +import com.att.research.xacml.std.StdStatusCode;
> +import com.att.research.xacml.util.ListUtil;
> +
> +/**
> + * ResultMatchResult provides information about how well a {@link
> com.att.research.xacml.api.Result} object matches
> + * another <code>Result</code> object.
> + *
> + * @author car
> + * @version $Revision: 1.1 $
> + */
> +public class ResultMatchResult {
> +	private boolean bAssociatedAdviceMatches	= true;
> +	private boolean bAttributesMatch			= true;
> +	private boolean bDecisionsMatch				= true;
> +	private boolean bObligationsMatch			= true;
> +	private boolean bPolicyIdentifiersMatch		= true;
> +	private boolean bPolicySetIdentifiersMatch	= true;
> +	private boolean bStatusCodesMatch			= true;
> +	private boolean bUnknownFunction			= false;
> +
> +	protected void setAssociatedAdviceMatches(boolean b) {
> +		this.bAssociatedAdviceMatches	= b;
> +	}
> +	protected void setAttributesMatch(boolean b) {
> +		this.bAttributesMatch	= b;
> +	}
> +	protected void setDecisionsMatch(boolean b) {
> +		this.bDecisionsMatch	= b;
> +	}
> +	protected void setObligationsMatch(boolean b) {
> +		this.bObligationsMatch	= b;
> +	}
> +	protected void setPolicyIdentifiersMatch(boolean b) {
> +		this.bPolicyIdentifiersMatch	= b;
> +	}
> +	protected void setPolicySetIdentifiersMatch(boolean b) {
> +		this.bPolicySetIdentifiersMatch	= b;
> +	}
> +	protected void setStatusCodesMatch(boolean b) {
> +		this.bStatusCodesMatch	= b;
> +	}
> +	protected void setUnknownFunction(boolean b) {
> +		this.bUnknownFunction	= b;
> +	}
> +
> +	public ResultMatchResult() {
> +	}
> +
> +	public static ResultMatchResult newInstance(Result result1,
> Result result2) {
> +		ResultMatchResult resultMatchResult	= new
> ResultMatchResult();
> +		if (result2 != null && result2.getStatus() != null &&
> +
> 	result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_C
> ODE_PROCESSING_ERROR) &&
> +			result2.getStatus().getStatusMessage() != null &&
> +
> 	result2.getStatus().getStatusMessage().contains("Unknown
> Function")
> +			) {
> +			resultMatchResult.setUnknownFunction(true);
> +		}
> +		if (result1 == null || result2 == null) {
> +			resultMatchResult.setAssociatedAdviceMatches(false);
> +			resultMatchResult.setAttributesMatch(false);
> +			resultMatchResult.setDecisionsMatch(false);
> +			resultMatchResult.setObligationsMatch(false);
> +			resultMatchResult.setPolicyIdentifiersMatch(false);
> +
> 	resultMatchResult.setPolicySetIdentifiersMatch(false);
> +			resultMatchResult.setStatusCodesMatch(false);
> +		} else {
> +
> 	resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllow
> Nulls(result1.getAssociatedAdvice(), result2.getAssociatedAdvice()));
> +
> 	resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(re
> sult1.getAttributes(), result2.getAttributes()));
> +
> 	resultMatchResult.setDecisionsMatch(result1.getDecision() ==
> result2.getDecision());
> +
> 	resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(r
> esult1.getObligations(), result2.getObligations()));
> +
> 	resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowN
> ulls(result1.getPolicyIdentifiers(), result2.getPolicyIdentifiers()));
> +
> 	resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAll
> owNulls(result1.getPolicySetIdentifiers(),
> result2.getPolicySetIdentifiers()));
> +			if (result1.getStatus() == null ||
> result1.getStatus().getStatusCode() == null || result2.getStatus() ==
> null || result2.getStatus().getStatusCode() == null) {
> +				resultMatchResult.setStatusCodesMatch(false);
> +			} else {
> +
> 	resultMatchResult.setStatusCodesMatch(result1.getStatus().getStat
> usCode().equals(result2.getStatus().getStatusCode()));
> +			}
> +		}
> +		return resultMatchResult;
> +	}
> +
> +	public boolean associatedAdviceMatches() {
> +		return this.bAssociatedAdviceMatches;
> +	}
> +
> +	public boolean attributesMatch() {
> +		return this.bAttributesMatch;
> +	}
> +
> +	public boolean decisionsMatch() {
> +		return this.bDecisionsMatch;
> +	}
> +
> +	public boolean obligationsMatch() {
> +		return this.bObligationsMatch;
> +	}
> +
> +	public boolean policyIdentifiersMatch() {
> +		return this.bPolicyIdentifiersMatch;
> +	}
> +
> +	public boolean policySetIdentifiersMatch() {
> +		return this.bPolicySetIdentifiersMatch;
> +	}
> +
> +	public boolean statusCodesMatch() {
> +		return this.bStatusCodesMatch;
> +	}
> +
> +	public boolean unknownFunction() {
> +		return this.bUnknownFunction;
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> TypeFactory.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> TypeFactory.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> TypeFactory.java
> new file mode 100755
> index 0000000..b3e6cc4
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomData
> TypeFactory.java
> @@ -0,0 +1,78 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.util.HashMap;
> +import java.util.Map;
> +
> +import com.att.research.xacml.api.DataType;
> +import com.att.research.xacml.api.DataTypeFactory;
> +import com.att.research.xacml.api.Identifier;
> +import com.att.research.xacml.std.datatypes.DataTypes;
> +
> +public class CustomDataTypeFactory extends DataTypeFactory {
> +	private static final Map<Identifier,DataType<?>>
> mapIdentifiersToDataTypes	= new HashMap<Identifier,DataType<?>>();
> +	private static boolean mapNeedsInit
> 							= true;
> +
> +	public static final DataTypePrivateKey
> 	DT_PRIVATEKEY				=
> DataTypePrivateKey.newInstance();
> +	public static final DataTypePublicKey
> 	DT_PUBLICKEY				=
> DataTypePublicKey.newInstance();
> +
> +	private static void registerDataType(DataType<?> dataType) {
> +		if (dataType != null && dataType.getId() != null) {
> +			mapIdentifiersToDataTypes.put(dataType.getId(),
> dataType);
> +		}
> +	}
> +
> +	private static void initMap() {
> +		if (mapNeedsInit) {
> +			synchronized(mapIdentifiersToDataTypes) {
> +				if (mapNeedsInit) {
> +					registerDataType(DataTypes.DT_ANYURI);
> +
> 	registerDataType(DataTypes.DT_BASE64BINARY);
> +					registerDataType(DataTypes.DT_BOOLEAN);
> +					registerDataType(DataTypes.DT_DATE);
> +					registerDataType(DataTypes.DT_DATETIME);
> +
> 	registerDataType(DataTypes.DT_DAYTIMEDURATION);
> +					registerDataType(DataTypes.DT_DNSNAME);
> +					registerDataType(DataTypes.DT_DOUBLE);
> +					registerDataType(DataTypes.DT_HEXBINARY);
> +					registerDataType(DataTypes.DT_INTEGER);
> +					registerDataType(DataTypes.DT_IPADDRESS);
> +
> 	registerDataType(DataTypes.DT_RFC822NAME);
> +					registerDataType(DataTypes.DT_STRING);
> +					registerDataType(DataTypes.DT_TIME);
> +					registerDataType(DataTypes.DT_X500NAME);
> +
> 	registerDataType(DataTypes.DT_XPATHEXPRESSION);
> +
> 	registerDataType(DataTypes.DT_YEARMONTHDURATION);
> +					//
> +					// These are the custom data types!
> +					//
> +					registerDataType(DT_PRIVATEKEY);
> +					registerDataType(DT_PUBLICKEY);
> +					//
> +					// Done
> +					//
> +					mapNeedsInit	= false;
> +				}
> +			}
> +		}
> +	}
> +
> +	public CustomDataTypeFactory() {
> +		initMap();
> +	}
> +
> +	@Override
> +	public DataType<?> getDataType(Identifier dataTypeId) {
> +		return mapIdentifiersToDataTypes.get(dataTypeId);
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> tionDefinitionFactory.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> tionDefinitionFactory.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> tionDefinitionFactory.java
> new file mode 100755
> index 0000000..dd4decb
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/CustomFunc
> tionDefinitionFactory.java
> @@ -0,0 +1,80 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.lang.reflect.Field;
> +import java.lang.reflect.Modifier;
> +import java.security.PrivateKey;
> +import java.security.PublicKey;
> +import java.util.HashMap;
> +import java.util.Map;
> +
> +import com.att.research.xacml.api.Identifier;
> +import com.att.research.xacml.std.IdentifierImpl;
> +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
> +import com.att.research.xacmlatt.pdp.policy.FunctionDefinitionFactory;
> +import com.att.research.xacmlatt.pdp.std.StdFunctions;
> +import
> com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAnd
> Only;
> +
> +public class CustomFunctionDefinitionFactory extends
> FunctionDefinitionFactory {
> +	private static Map<Identifier,FunctionDefinition>
> 	mapFunctionDefinitions	= new
> HashMap<Identifier,FunctionDefinition>();
> +	private static boolean
> 	needMapInit				= true;
> +
> +	public static final Identifier
> ID_FUNCTION_PRIVATEKEY_ONE_AND_ONLY = new
> IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:priv
> atekey-one-and-only");
> +	public static final Identifier ID_FUNCTION_PUBLICKEY_ONE_AND_ONLY
> = new
> IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:publ
> ickey-one-and-only");
> +
> +	public static final FunctionDefinition
> 	FD_PRIVATEKEY_ONE_AND_ONLY	= new
> FunctionDefinitionBagOneAndOnly<PrivateKey>(ID_FUNCTION_PRIVATEKEY_ONE_
> AND_ONLY, DataTypePrivateKey.newInstance());
> +	public static final FunctionDefinition
> 	FD_PUBLICKEY_ONE_AND_ONLY	= new
> FunctionDefinitionBagOneAndOnly<PublicKey>(ID_FUNCTION_PUBLICKEY_ONE_AN
> D_ONLY, DataTypePublicKey.newInstance());
> +
> +	private static void register(FunctionDefinition
> functionDefinition) {
> +		mapFunctionDefinitions.put(functionDefinition.getId(),
> functionDefinition);
> +	}
> +
> +	private static void initMap() {
> +		if (needMapInit) {
> +			synchronized(mapFunctionDefinitions) {
> +				if (needMapInit) {
> +					needMapInit	= false;
> +					Field[] declaredFields	=
> StdFunctions.class.getDeclaredFields();
> +					for (Field field : declaredFields) {
> +						if
> (Modifier.isStatic(field.getModifiers()) &&
> +
> 	field.getName().startsWith(StdFunctions.FD_PREFIX) &&
> +
> 	FunctionDefinition.class.isAssignableFrom(field.getType()) &&
> +
> 	Modifier.isPublic(field.getModifiers())
> +						) {
> +							try {
> +
> 	register((FunctionDefinition)(field.get(null)));
> +							} catch
> (IllegalAccessException ex) {
> +
> +							}
> +						}
> +					}
> +					//
> +					// Our custom function
> +					//
> +
> 	register(FunctionDefinitionDecrypt.newInstance());
> +					register(FD_PRIVATEKEY_ONE_AND_ONLY);
> +					register(FD_PUBLICKEY_ONE_AND_ONLY);
> +				}
> +			}
> +		}
> +	}
> +
> +	public CustomFunctionDefinitionFactory() {
> +		initMap();
> +	}
> +
> +	@Override
> +	public FunctionDefinition getFunctionDefinition(Identifier
> functionId) {
> +		return mapFunctionDefinitions.get(functionId);
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> ivateKey.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> ivateKey.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> ivateKey.java
> new file mode 100755
> index 0000000..4e12aef
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePr
> ivateKey.java
> @@ -0,0 +1,44 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.security.PrivateKey;
> +
> +import com.att.research.xacml.api.DataTypeException;
> +import com.att.research.xacml.api.Identifier;
> +import com.att.research.xacml.std.IdentifierImpl;
> +import com.att.research.xacml.std.datatypes.DataTypeBase;
> +
> +public class DataTypePrivateKey extends DataTypeBase<PrivateKey> {
> +	public static final Identifier DT_PRIVATEKEY = new
> IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:private");
> +	private static final DataTypePrivateKey singleInstance = new
> DataTypePrivateKey();
> +
> +	private DataTypePrivateKey() {
> +		super(DT_PRIVATEKEY, PrivateKey.class);
> +	}
> +
> +	public static DataTypePrivateKey newInstance() {
> +		return singleInstance;
> +	}
> +
> +	@Override
> +	public PrivateKey convert(Object source) throws DataTypeException
> {
> +		if (source == null || (source instanceof PrivateKey) ) {
> +			return (PrivateKey) source;
> +		} else if (source instanceof byte[]) {
> +			return (PrivateKey) source;
> +		} else if (source instanceof String) {
> +			return (PrivateKey) (Object) ((String)
> source).getBytes();
> +		}
> +		throw new DataTypeException(this, "Failed to convert \"" +
> source.getClass().getCanonicalName());
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> blicKey.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> blicKey.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> blicKey.java
> new file mode 100755
> index 0000000..d40ee82
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/DataTypePu
> blicKey.java
> @@ -0,0 +1,44 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.security.PublicKey;
> +
> +import com.att.research.xacml.api.DataTypeException;
> +import com.att.research.xacml.api.Identifier;
> +import com.att.research.xacml.std.IdentifierImpl;
> +import com.att.research.xacml.std.datatypes.DataTypeBase;
> +
> +public class DataTypePublicKey extends DataTypeBase<PublicKey> {
> +	public static final Identifier DT_PUBLICKEY = new
> IdentifierImpl("urn:com:att:research:xacml:custom:3.0:rsa:public");
> +	private static final DataTypePublicKey singleInstance = new
> DataTypePublicKey();
> +
> +	public DataTypePublicKey() {
> +		super(DT_PUBLICKEY, PublicKey.class);
> +	}
> +
> +	public static DataTypePublicKey newInstance() {
> +		return singleInstance;
> +	}
> +
> +	@Override
> +	public PublicKey convert(Object source) throws DataTypeException
> {
> +		if (source == null || (source instanceof PublicKey) ) {
> +			return (PublicKey) source;
> +		} else if (source instanceof byte[]) {
> +			return (PublicKey) source;
> +		} else if (source instanceof String) {
> +			return (PublicKey) (Object) ((String)
> source).getBytes();
> +		}
> +		throw new DataTypeException(this, "Failed to convert \"" +
> source.getClass().getCanonicalName());
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> finitionDecrypt.java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> finitionDecrypt.java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> finitionDecrypt.java
> new file mode 100755
> index 0000000..d51c73d
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/FunctionDe
> finitionDecrypt.java
> @@ -0,0 +1,152 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.security.InvalidKeyException;
> +import java.security.NoSuchAlgorithmException;
> +import java.security.PrivateKey;
> +import java.security.PublicKey;
> +import java.util.List;
> +
> +import javax.crypto.BadPaddingException;
> +import javax.crypto.Cipher;
> +import javax.crypto.IllegalBlockSizeException;
> +import javax.crypto.NoSuchPaddingException;
> +
> +import com.att.research.xacml.api.DataType;
> +import com.att.research.xacml.api.DataTypeException;
> +import com.att.research.xacml.api.Identifier;
> +import com.att.research.xacml.api.XACML3;
> +import com.att.research.xacml.std.IdentifierImpl;
> +import com.att.research.xacml.std.StdStatus;
> +import com.att.research.xacml.std.StdStatusCode;
> +import com.att.research.xacml.std.datatypes.DataTypeHexBinary;
> +import com.att.research.xacml.std.datatypes.DataTypeString;
> +import com.att.research.xacml.std.datatypes.HexBinary;
> +import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
> +import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
> +import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
> +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
> +import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
> +
> +public class FunctionDefinitionDecrypt implements FunctionDefinition {
> +	public static final Identifier FD_RSA_DECRYPT = new
> IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decr
> ypt");
> +	private static final FunctionDefinitionDecrypt singleInstance =
> new FunctionDefinitionDecrypt();
> +
> +	public static FunctionDefinitionDecrypt newInstance() {
> +		return singleInstance;
> +	}
> +
> +	@Override
> +	public Identifier getId() {
> +		return FD_RSA_DECRYPT;
> +	}
> +
> +	@Override
> +	public Identifier getDataTypeId() {
> +		return XACML3.ID_DATATYPE_STRING;
> +	}
> +
> +	@Override
> +	public boolean returnsBag() {
> +		return false;
> +	}
> +
> +	@Override
> +	public ExpressionResult evaluate(EvaluationContext
> evaluationContext, List<FunctionArgument> arguments) {
> +		if (arguments == null || arguments.size() < 2) {
> +			return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> expecting 2 arguments."));
> +		}
> +		//
> +		// What is the first argument?
> +		//
> +		FunctionArgument arg0 = arguments.get(0);
> +		if (arg0.isBag()) {
> +			//
> +			// We don't support bags right now
> +			//
> +			return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> not expecting a bag for argument 0."));
> +		}
> +		if
> (arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY)
> == false) {
> +			//
> +			// Should be a String
> +			//
> +			return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> expected a Hex Binary for argument 0."));
> +		}
> +		//
> +		// Convert the argument
> +		//
> +		ConvertedArgument<HexBinary> data = new
> ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(),
> false);
> +		if (! data.isOk()) {
> +			return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> argument 0 failed to convert to Hex Binary."));
> +		}
> +		//
> +		// Ok - check the 2nd argument
> +		//
> +		FunctionArgument arg1 = arguments.get(1);
> +		if (arg1.isBag()) {
> +			//
> +			// We don't support bags right now
> +			//
> +			return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> not expecting a bag for argument 1."));
> +		}
> +		if
> (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKE
> Y) ||
> +
> 	arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLI
> CKEY)) {
> +			//
> +			// Ok - let's try to decrypt
> +			//
> +			Cipher cipher;
> +			try {
> +				cipher = Cipher.getInstance("RSA");
> +				if
> (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKE
> Y)) {
> +					//
> +					// Using the private key
> +					//
> +					DataType<PrivateKey> pkDatatype =
> DataTypePrivateKey.newInstance();
> +					ConvertedArgument<PrivateKey> privateKey
> = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
> +					if ( ! privateKey.isOk()) {
> +						return
> ExpressionResult.newError(new
> StdStatus(privateKey.getStatus().getStatusCode(), "Decrypt: " +
> privateKey.getStatus().getStatusMessage()));
> +					}
> +					//
> +					// Setup decryption
> +					//
> +					cipher.init(Cipher.DECRYPT_MODE,
> privateKey.getValue());
> +				} else if
> (arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)
> ) {
> +					//
> +					// Using the private key
> +					//
> +					DataType<PublicKey> pkDatatype =
> DataTypePublicKey.newInstance();
> +					ConvertedArgument<PublicKey> publicKey =
> new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
> +					if ( ! publicKey.isOk()) {
> +						return
> ExpressionResult.newError(new
> StdStatus(publicKey.getStatus().getStatusCode(), "Decrypt: " +
> publicKey.getStatus().getStatusMessage()));
> +					}
> +					//
> +					// Setup decryption
> +					//
> +					cipher.init(Cipher.DECRYPT_MODE,
> publicKey.getValue());
> +				}
> +				//
> +				// Do the decryption
> +				//
> +				byte[] decryptedData =
> cipher.doFinal(data.getValue().getData());
> +				String decryptedString = new
> String(decryptedData);
> +				//
> +				// All good, return the decrypted string
> +				//
> +				return
> ExpressionResult.newSingle(DataTypeString.newInstance().createAttribute
> Value(decryptedString));
> +			} catch (NoSuchAlgorithmException |
> NoSuchPaddingException | InvalidKeyException |
> IllegalBlockSizeException | BadPaddingException | DataTypeException e)
> {
> +				return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed:
> " + e.getLocalizedMessage()));
> +			}
> +		}
> +		return ExpressionResult.newError(new
> StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed,
> expecting public/private key datatype for argument 1."));
> +	}
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-
> openaz/blob/94fcdd90/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> .java
> ----------------------------------------------------------------------
> diff --git a/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> .java b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> .java
> new file mode 100755
> index 0000000..df93001
> --- /dev/null
> +++ b/openaz-xacml-
> test/src/test/java/com/att/research/xacmlatt/pdp/test/custom/TestCustom
> .java
> @@ -0,0 +1,384 @@
> +/*
> + *                        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.xacmlatt.pdp.test.custom;
> +
> +import java.io.IOException;
> +import java.io.ObjectInputStream;
> +import java.io.ObjectOutputStream;
> +import java.net.MalformedURLException;
> +import java.nio.file.Files;
> +import java.nio.file.Path;
> +import java.nio.file.Paths;
> +import java.security.InvalidKeyException;
> +import java.security.KeyPair;
> +import java.security.KeyPairGenerator;
> +import java.security.NoSuchAlgorithmException;
> +import java.security.PrivateKey;
> +import java.security.PublicKey;
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +import javax.crypto.BadPaddingException;
> +import javax.crypto.Cipher;
> +import javax.crypto.IllegalBlockSizeException;
> +import javax.crypto.NoSuchPaddingException;
> +
> +import org.apache.commons.cli.CommandLine;
> +import org.apache.commons.cli.GnuParser;
> +import org.apache.commons.cli.Option;
> +import org.apache.commons.cli.ParseException;
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +import com.att.research.xacml.api.AttributeValue;
> +import com.att.research.xacml.api.DataType;
> +import com.att.research.xacml.api.DataTypeException;
> +import com.att.research.xacml.api.Request;
> +import com.att.research.xacml.api.RequestAttributes;
> +import com.att.research.xacml.api.XACML3;
> +import com.att.research.xacml.api.pep.PEPException;
> +import com.att.research.xacml.std.IdentifierImpl;
> +import com.att.research.xacml.std.StdMutableAttribute;
> +import com.att.research.xacml.std.StdMutableRequest;
> +import com.att.research.xacml.std.StdMutableRequestAttributes;
> +import com.att.research.xacml.std.dom.DOMStructureException;
> +import com.att.research.xacml.std.json.JSONStructureException;
> +import com.att.research.xacml.util.FactoryException;
> +import com.att.research.xacmlatt.pdp.test.TestBase;
> +
> +/**
> + * TestCustom is an application that tests the extensibility and
> configurability of the AT&T XACML API.
> + *
> + * It creates a custom datatype definition factory that adds in custom
> data types for RSA
> + * PublicKey and PrivateKey.
> + *
> + * It creates a custom function definition factory that adds in custom
> decryption function for decrypting data. It
> + * also derives and loads custom functions for the RSA public/private
> key datatypes for the bag function: one-and-only.
> + *
> + * @author pameladragosh
> + *
> + */
> +public class TestCustom extends TestBase {
> +	private static final Log logger	=
> LogFactory.getLog(TestCustom.class);
> +
> +	//
> +	// Our public's
> +	//
> +	public static final String ALGORITHM = "RSA";
> +	public static final String PRIVATEKEY_FILE = "PrivateKey.key";
> +	public static final String PUBLICKEY_FILE = "PublicKey.key";
> +
> +	public static final String DECRYPTION_INPUT_STRING = "This is the
> SECRET value!";
> +
> +	public static final String DECRYPTION_INPUT_ID =
> "com:att:research:xacml:test:custom:encrypted-data";
> +	//
> +	// Our keys
> +	//
> +	protected PublicKey publicKey = null;
> +	protected PrivateKey privateKey = null;
> +	//
> +	// Our command line parameters
> +	//
> +	public static final String OPTION_GENERATE = "generate";
> +
> +	static {
> +		options.addOption(new Option(OPTION_GENERATE, false,
> "Generate a private/public key pair."));
> +	}
> +
> +	/**
> +	 * This function generates the public/private key pair. Should
> never have to call this again, this was
> +	 * called once to generate the keys. They were saved into the
> testsets/custom/datatype-function sub-directory.
> +	 */
> +	public void generateKeyPair() {
> +		//
> +		// Generate a RSA private/public key pair
> +		//
> +		KeyPairGenerator keyGen;
> +		try {
> +			keyGen = KeyPairGenerator.getInstance(ALGORITHM);
> +		} catch (NoSuchAlgorithmException e) {
> +			logger.error("failed to generate keypair: " + e);
> +			return;
> +		}
> +		keyGen.initialize(1024);
> +		final KeyPair key = keyGen.generateKeyPair();
> +		//
> +		// Save the keys to disk
> +		//
> +		Path file = Paths.get(this.directory, PRIVATEKEY_FILE);
> +		try (ObjectOutputStream os = new
> ObjectOutputStream(Files.newOutputStream(file))) {
> +			os.writeObject(key.getPrivate());
> +		} catch (IOException e) {
> +			e.printStackTrace();
> +		}
> +		file = Paths.get(this.directory, PUBLICKEY_FILE);
> +		try (ObjectOutputStream os = new
> ObjectOutputStream(Files.newOutputStream(file))) {
> +			os.writeObject(key.getPublic());
> +		} catch (IOException e) {
> +			e.printStackTrace();
> +		}
> +	}
> +
> +	public TestCustom(String[] args) throws ParseException,
> MalformedURLException, HelpException {
> +		super(args);
> +	}
> +
> +	/* (non-Javadoc)
> +	 *
> +	 * Simply look for command line option: -generate
> +	 * This generates the public/private key. Shouldn't need to call
> it again, the keys have
> +	 * already been generated and saved.
> +	 *
> +	 * @see
> com.att.research.xacmlatt.pdp.test.TestBase#parseCommands(java.lang.Str
> ing[])
> +	 */
> +	@Override
> +	protected void parseCommands(String[] args) throws
> ParseException, MalformedURLException, HelpException {
> +		//
> +		// Have our parent class parse its options out
> +		//
> +		super.parseCommands(args);
> +		//
> +		// Parse the command line options
> +		//
> +		CommandLine cl;
> +		cl = new GnuParser().parse(options, args);
> +		if (cl.hasOption(OPTION_GENERATE)) {
> +			//
> +			// Really only need to do this once to setup the
> test.
> +			//
> +			this.generateKeyPair();
> +		}
> +	}
> +
> +	/* (non-Javadoc)
> +	 *
> +	 * After our parent class configure's itself, all this needs to
> do is read in
> +	 * the public/private key's into objects.
> +	 *
> +	 * @see com.att.research.xacmlatt.pdp.test.TestBase#configure()
> +	 */
> +	@Override
> +	protected void configure() throws FactoryException {
> +		//
> +		// Have our super do its thing
> +		//
> +		super.configure();
> +		//
> +		// Read in the public key
> +		//
> +		try {
> +			this.publicKey = (PublicKey) new
> ObjectInputStream(Files.newInputStream(Paths.get(this.directory,
> PUBLICKEY_FILE))).readObject();
> +		} catch (ClassNotFoundException | IOException e) {
> +			logger.error(e);
> +		}
> +		//
> +		// Read in the private key
> +		//
> +		try {
> +			this.privateKey = (PrivateKey) new
> ObjectInputStream(Files.newInputStream(Paths.get(this.directory,
> PRIVATEKEY_FILE))).readObject();
> +		} catch (ClassNotFoundException | IOException e) {
> +			logger.error(e);
> +		}
> +	}
> +
> +	/* (non-Javadoc)
> +	 *
> +	 * Here we add 2 attributes into the request: 1) the private key,
> and 2) a String that was encrypted using the public key.
> +	 *
> +	 * The goal is to have the custom decrypt function use the
> private key to decrypt that string.
> +	 *
> +	 * @see
> com.att.research.xacmlatt.pdp.test.TestBase#generateRequest(java.nio.fi
> le.Path, java.lang.String)
> +	 */
> +	@Override
> +	protected Request generateRequest(Path file, String group) throws
> JSONStructureException, DOMStructureException, PEPException {
> +		//
> +		// Have our super class do its work
> +		//
> +		Request oldRequest = super.generateRequest(file, group);
> +		//
> +		// Copy the request attributes
> +		//
> +		List<StdMutableRequestAttributes> attributes = new
> ArrayList<StdMutableRequestAttributes>();
> +		for (RequestAttributes a :
> oldRequest.getRequestAttributes()) {
> +			attributes.add(new StdMutableRequestAttributes(a));
> +		}
> +		//
> +		// We are supplying the private key as an attribute for the
> decryption function to use:
> +		//
> +		// (NOTE: Ideally this would be provided by a custom PIP
> provider, not the PEP)
> +		//
> +		// ID=com:att:research:xacml:test:custom:privatekey
> +		// Issuer=com:att:research:xacml:test:custom
> +		// Category=urn:oasis:names:tc:xacml:1.0:subject-
> category:access-subject
> +		//
> Datatype=urn:com:att:research:xacml:custom:3.0:rsa:private
> +		//
> +		DataType<?> dtExtended =
> dataTypeFactory.getDataType(DataTypePrivateKey.DT_PRIVATEKEY);
> +		if (dtExtended == null) {
> +			logger.error("Failed to get private key datatype.");
> +			return null;
> +		}
> +		//
> +		// Create the attribute value
> +		//
> +		try {
> +			AttributeValue<?> attributeValue =
> dtExtended.createAttributeValue(this.privateKey);
> 
> +			//
> +			// Create the attribute
> +			//
> +			StdMutableAttribute newAttribute = new
> StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
> +
> 							new
> IdentifierImpl("com:att:research:xacml:test:custom:privatekey"),
> +
> 							attributeValue,
> +
> 
> 	"com:att:research:xacml:test:custom",
> +
> 							false);
> +			boolean added = false;
> +			for (StdMutableRequestAttributes a : attributes) {
> +				//
> +				// Does the category exist?
> +				//
> +				if
> (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
> +					//
> +					// Yes - add in the new attribute value
> +					//
> +					a.add(newAttribute);
> +					added = true;
> +					break;
> +				}
> +			}
> +			if (added == false) {
> +				//
> +				// New category - create it and add it in
> +				//
> +				StdMutableRequestAttributes a = new
> StdMutableRequestAttributes();
> +				a.setCategory(newAttribute.getCategory());
> +				a.add(newAttribute);
> +				attributes.add(a);
> +			}
> +		} catch (DataTypeException e) {
> +			logger.error(e);
> +			return null;
> +		}
> +		//
> +		// We are also supplying this attribute which is the secret
> text encrypted with
> +		// the public key.
> +		//
> +		// ID=com:att:research:xacml:test:custom:encrypted-data
> +		// Issuer=
> +		// Category=urn:oasis:names:tc:xacml:1.0:subject-
> category:access-subject
> +		// Datatype=http://www.w3.org/2001/XMLSchema#hexBinary
> +		//
> +		// Encrypt it
> +		//
> +		byte[] encryptedData = null;
> +		try {
> +			Cipher cipher = Cipher.getInstance(ALGORITHM);
> +			cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
> +			//
> +			// This is just a hack to test a decryption of the
> wrong value.
> +			//
> +			if (group.equals("Permit")) {
> +				encryptedData =
> cipher.doFinal(DECRYPTION_INPUT_STRING.getBytes());
> +			} else {
> +				encryptedData = cipher.doFinal("This is NOT the
> secret".getBytes());
> +			}
> +		} catch (NoSuchAlgorithmException | NoSuchPaddingException
> | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
> e) {
> +			logger.error(e);
> +			return null;
> +		}
> +		//
> +		// Sanity check (for the Permit request)
> +		//
> +		try {
> +			if (group.equals("Permit")) {
> +				Cipher cipher = Cipher.getInstance(ALGORITHM);
> +				cipher.init(Cipher.DECRYPT_MODE,
> this.privateKey);
> +				byte[] decryptedData =
> cipher.doFinal(encryptedData);
> +				if (new
> String(decryptedData).equals(DECRYPTION_INPUT_STRING)) {
> +					logger.info("Sanity check passed:
> decrypted the encrypted data.");
> +				} else {
> +					logger.error("Sanity check failed to
> decrypt the encrypted data.");
> +					return null;
> +				}
> +			}
> +		} catch (NoSuchAlgorithmException | NoSuchPaddingException
> | InvalidKeyException | IllegalBlockSizeException | BadPaddingException
> e) {
> +			logger.error(e);
> +		}
> +		//
> +		// Get our datatype factory
> +		//
> +		dtExtended =
> dataTypeFactory.getDataType(XACML3.ID_DATATYPE_HEXBINARY);
> +		if (dtExtended == null) {
> +			logger.error("Failed to get hex binary datatype.");
> +			return null;
> +		}
> +		//
> +		// Create the attribute value
> +		//
> +		try {
> +			AttributeValue<?> attributeValue =
> dtExtended.createAttributeValue(encryptedData);
> 
> +			//
> +			// Create the attribute
> +			//
> +			StdMutableAttribute newAttribute = new
> StdMutableAttribute(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT,
> +
> 							new
> IdentifierImpl("com:att:research:xacml:test:custom:encrypted-data"),
> +
> 							attributeValue,
> +
> 							null,
> +
> 							false);
> +			boolean added = false;
> +			for (StdMutableRequestAttributes a : attributes) {
> +				//
> +				// Does the category exist?
> +				//
> +				if
> (a.getCategory().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
> +					//
> +					// Yes - add in the new attribute value
> +					//
> +					a.add(newAttribute);
> +					added = true;
> +					break;
> +				}
> +			}
> +			if (added == false) {
> +				//
> +				// New category - create it and add it in
> +				//
> +				StdMutableRequestAttributes a = new
> StdMutableRequestAttributes();
> +				a.setCategory(newAttribute.getCategory());
> +				a.add(newAttribute);
> +				attributes.add(a);
> +			}
> +		} catch (DataTypeException e) {
> +			logger.error(e);
> +			return null;
> +		}
> +		//
> +		// Now form our final request
> +		//
> +		StdMutableRequest newRequest = new StdMutableRequest();
> +
> 	newRequest.setCombinedDecision(oldRequest.getCombinedDecision());
> +
> 	newRequest.setRequestDefaults(oldRequest.getRequestDefaults());
> +
> 	newRequest.setReturnPolicyIdList(oldRequest.getReturnPolicyIdList
> ());
> +		newRequest.setStatus(oldRequest.getStatus());
> +		for (StdMutableRequestAttributes a : attributes) {
> +			newRequest.add(a);
> +		}
> +		return newRequest;
> +	}
> +
> +	public static void main(String[] args) {
> +		try {
> +			new TestCustom(args).run();
> +		} catch (ParseException | IOException | FactoryException e)
> {
> +			logger.error(e);
> +		} catch (HelpException e) {
> +		}
> +	}
> +
> +}
>