diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2017-02-14 19:41:00 -0500 |
---|---|---|
committer | Pamela Dragosh <pdragosh@research.att.com> | 2017-02-14 19:41:32 -0500 |
commit | 91d04c64771832a0b8815ffbe1f0f9920320d94d (patch) | |
tree | fb02d5e1c84a3d91def9a7ee95bc87f9c046cc96 /ECOMP-XACML/src/test/java/org | |
parent | b9d4caa40ef8e3566ac475968bce17b9b64b6939 (diff) |
Initial OpenECOMP policy/engine commit
Change-Id: I7dbff37733b661643dd4d1caefa3d7dccc361b6e
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
Diffstat (limited to 'ECOMP-XACML/src/test/java/org')
13 files changed, 14355 insertions, 0 deletions
diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseConformanceTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseConformanceTest.java new file mode 100644 index 000000000..2083577c7 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseConformanceTest.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Response; +import com.att.research.xacml.std.dom.DOMResponse; + +/** + * Tests for handling the XML version of the XACML Response object. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * Normally the Response is generated by the PDP and returned through the RESTful interface as JSON. + * Testing of the XML interface is minimal and not complete. + * + * + * + * + */ +public class DOMResponseConformanceTest { + + // where to find the conformance test XML files + private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4"; + + // The request object output from each test conversion from JSON string + Response response; + + + + // Load the Conformance test responses into Response objects, generate the output XML for that Response and compare with the original files. + @Test + public void testDOMResponse() { + List<File> filesInDirectory = null; + + File conformanceDirectory = null; + + File currentFile = null; + + try { + conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH); + filesInDirectory = getRequestsInDirectory(conformanceDirectory); + } catch (Exception e) { + fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e); + } + + // run through each XML file + // - load the file from XML into an internal Response object + // - generate the XML representation from that Response object + // - reload the file into a String + // - compare the 2 XML strings + Response xmlResponse = null; + try { + for (File f : filesInDirectory) { + currentFile = f; + +//// This is a simple way to select just one file for debugging - comment out when not being used +//if ( ! f.getName().equals("IID302Response.xml")) { continue; } + +// during debugging it is helpful to know what file it is starting to work on +// System.out.println("starting file="+currentFile.getName()); + + + BufferedReader br = new BufferedReader(new FileReader(f)); + StringBuffer sb = new StringBuffer(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + + String xmlFromFile = sb.toString(); + + try { + // load XML into a Response object + xmlResponse = DOMResponse.load(xmlFromFile); + } catch (Exception e) { + // if XML does not load, just note it and continue with next file + System.out.println("XML file did not load: '" + f.getName() + " e=" + e); + continue; + } +//System.out.println(xmlFromFile); + + // create String version from the Response object + String xmlResponseString = DOMResponse.toString(xmlResponse, false); + + // Comparing the string directly to the String from the file is difficult. + // We can minimize the problems with newlines and whitespace, but we have other issues with how various object values are represented. + // For instance, and input double of "23.50" is output as "23.5" which is the same value but not identical strings. + // Therefore we take the XML output and use it to create a new Response object, then compare the two objects. + +//System.out.println(xmlResponseString); + Response reGeneratedResponse = DOMResponse.load(xmlResponseString); + + if ( ! xmlResponse.equals(reGeneratedResponse)) { + String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", ""); + normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " "); + normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><"); + System.out.println("File="+normalizedFromFile); + System.out.println("Gend="+ xmlResponseString); + + System.out.println(DOMResponse.toString(xmlResponse, true)); + + fail("Output string did not re-generate eqivilent object."); + } + +// // Normally whitespace is significant in XML. +// // However in this case we are generating an XML string for output and comparing it to a hand-made file. +// // The file may contain extra newlines or fewer spaces then our prettyPrinted output version. +// // Therefore we do the comparison on the un-prettyPrinted generated string. +// // To do this we have to remove the extra whitespace from the version read from the file. +// String normalizedFromFile = xmlFromFile.replaceAll("\\r|\\n", ""); +// normalizedFromFile = normalizedFromFile.replaceAll("\\s+", " "); +// normalizedFromFile = normalizedFromFile.replaceAll(">\\s*<", "><"); +// +// if ( ! xmlResponseString.equals(normalizedFromFile)) { +// System.out.println("file="+normalizedFromFile+"\ngend="+xmlResponseString); +// fail("file not same as generated string: " + f.getName()+ "\nFile="+xmlFromFile + "\nString="+xmlResponseString); +// } + + + } + + } catch (Exception e) { + fail ("Failed test with '" + currentFile.getName() + "', e=" + e); + } + + + } + + + + // + // HELPER to get list of all Request files in the given directory + // + + private List<File> getRequestsInDirectory(File directory) { + List<File> fileList = new ArrayList<File>(); + + File[] fileArray = directory.listFiles(); + for (File f : fileArray) { + if (f.isDirectory()) { + List<File> subDirList = getRequestsInDirectory(f); + fileList.addAll(subDirList); + } + if (f.getName().endsWith("Response.xml")) { + fileList.add(f); + } + } + return fileList; + + } + + +} + + +/* +Place to edit long strings output during tests + + + + + + + + +*/ diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseTest.java new file mode 100644 index 000000000..5c27018d3 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/DOMResponseTest.java @@ -0,0 +1,2316 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Decision; +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.StdAttribute; +import com.att.research.xacml.std.StdAttributeCategory; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdIdReference; +import com.att.research.xacml.std.StdMutableAdvice; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.StdMutableAttributeAssignment; +import com.att.research.xacml.std.StdMutableMissingAttributeDetail; +import com.att.research.xacml.std.StdMutableObligation; +import com.att.research.xacml.std.StdMutableResponse; +import com.att.research.xacml.std.StdMutableResult; +import com.att.research.xacml.std.StdMutableStatus; +import com.att.research.xacml.std.StdMutableStatusDetail; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.StdVersion; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.StringNamespaceContext; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.dom.DOMStructureException; + +/** + * Test DOM XML Responses + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * This class was copied from the JSON tests. At this time only the first two methods have been revised to work with XML. + * The second method includes multiple instances of all possible fields and has been manually verified. + * The remaining methods have not been converted because: + * - "conversion" consists of replacing the JSON strings with XML + * - the replacement would consist of copying the XML from the JUnit output and doing a String replace + * - there would be little examination of the (long) XML strings, so their validity would be questionable + * so the benefit for the cost of doing that work is not clear. + * + * + */ +public class DOMResponseTest { + + String xmlResponse; + + StdMutableResponse response; + + StdMutableResult result; + + StdMutableStatus status; + + + // Note: Initially test responses without Obligations, Associated Advice, Attributes, or PolicyIdentifier + + + @Test + public void testEmptyAndDecisions() { + // null response + try { + xmlResponse = DOMResponse.toString(null, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // empty response (no Result object) + response = new StdMutableResponse(); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // just decision, no status + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // just status (empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // just status (non-empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setStatus(status); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // test other decisions without Status + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.DENY); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.NOTAPPLICABLE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENY); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - success + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + StdMutableResult result2 = new StdMutableResult(); + result2.setDecision(Decision.DENY); + response.add(result2); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Deny</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - one success and one error + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + result2 = new StdMutableResult(); + result2.setDecision(Decision.INDETERMINATE); + response.add(result2); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision></Result><Result><Decision>Indeterminate</Decision></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // Test with every field filled in with multiple values where appropriate + @Test + public void testAllFieldsResponse() { + + // fully-loaded multiple response + + StdMutableResponse response = new StdMutableResponse(); + // create a Status object + StdMutableStatus status = new StdMutableStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("some status message"); + StdMutableStatusDetail statusDetailIn = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "doh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "5432")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.setAttributeId(XACML3.ID_ACTION_PURPOSE); + mad.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION); + mad.setDataTypeId(XACML3.ID_DATATYPE_STRING); + mad.setIssuer("an Issuer"); + statusDetailIn.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetailIn); + // create a single result object + StdMutableResult result = new StdMutableResult(status); + // set the decision + result.setDecision(Decision.INDETERMINATE); + // put the Result into the Response + response.add(result); + + + // create a new Result with a different Decision + status = new StdMutableStatus(StdStatusCode.STATUS_CODE_OK); + result = new StdMutableResult(status); + result.setDecision(Decision.DENY); + + StdMutableObligation obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer2", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned"))); + result.addObligation(obligation); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_SUBJECT_CATEGORY_INTERMEDIARY_SUBJECT); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer3", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer4", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer"))); + result.addObligation(obligation); + + + StdMutableAdvice advice = new StdMutableAdvice(); + advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"))); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "advice-issuerNoCategory", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Crusty"))); + result.addAdvice(advice); + + + response.add(result); + + + // create a new Result with a different Decision + // add Child/minor status codes within the main status + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + + status = new StdMutableStatus(statusCode); + + + result = new StdMutableResult(status); + result.setDecision(Decision.PERMIT); + + + + + // add attribute list in result + Identifier categoryIdentifier = new IdentifierImpl("firstCategory"); + Attribute[] attrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(attrList))); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + + + // add PolicyIdentifierList to result + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + + response.add(result); + + // convert Response to XML + try { + xmlResponse = DOMResponse.toString(response, false); +//System.out.println(xmlResponse); +//System.out.println(DOMResponse.toString(response, true)); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>some status message</StatusMessage><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:action:purpose\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\" Issuer=\"an Issuer\"><AttributeValue>doh</AttributeValue><AttributeValue>5432</AttributeValue><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeAssignment></Obligation><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeAssignment></Obligation></Obligations><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Crusty</AttributeAssignment></Advice></AssociatedAdvice></Result><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode></Status><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // combinations of Status values with Decision values + @Test + public void testDecisionStatusMatch() { + // the tests in this method use different values and do not change structures, so we can re-use the objects + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + + // StatusCode = OK + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Deny</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>NotApplicable</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + + + + // StatusCode = SyntaxError + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // StatusCode = ProcessingError + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // StatusCode = MissingAttribute + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + result.setDecision(Decision.PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{D}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{DP}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate{P}</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // tests related to Status and its components + @Test + public void testStatus() { + // Status with no StatusCode - error + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusMessage when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + StdMutableStatusDetail statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusMessage when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // Status with StatusMessage when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + // Status with StatusMessage when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // Status with StatusDetail with empty detail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusDetail with valid detail with no value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with array valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>meh</AttributeValue><AttributeValue>nu?</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Status with StatusDetail with valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with array valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111)); + mad.addAttributeValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222)); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Indeterminate</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"/><StatusDetail><MissingAttributeDetail Category=\"urn:oasis:names:tc:xacml:1.0:action\" AttributeId=\"mad\" DataTypeId=\"http://www.w3.org/2001/XMLSchema#string\"><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue></MissingAttributeDetail></StatusDetail></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + +// StringNamespaceContext snc = new StringNamespaceContext(); +// try { +// snc.add("defaultURI"); +// snc.add("md", "referenceForMD"); +// } catch (Exception e) { +// fail("unable to create NamespaceContext e="+e); +// } +// XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); +// +//TODO - assume that we will never try to pass back an XPathExpression in a MissingAttributeDetail - it doesn't make sense and is unclear how to put into XML +// // Status with StatusDetail with valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// xmlResponse = DOMResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } +// +// // Status with StatusDetail with array valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId1"))); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId2"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// xmlResponse = DOMResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail><AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", xmlResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } + +//TODO - try with other data types, esp XPathExpression + + // Status with StatusDetail with array valid detail with value when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Status with StatusDetail with array valid detail with value when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // Status with nested child StatusCodes (child status containing child status containing...) + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode")); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"/></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Status><StatusCode Value=\"urn:oasis:names:tc:xacml:1.0:status:ok\"><StatusCode Value=\"child1StatusCode\"><StatusCode Value=\"childChildStatusCode\"><StatusCode Value=\"childChildChildStatusCode\"/></StatusCode></StatusCode></StatusCode><StatusMessage>I'm ok, you're ok</StatusMessage></Status></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + @Test + public void testObligations() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableObligation obligation; + + // test Obligation single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // obligation missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + null)); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing required DataType (Different than JSON where DataType is optional with default String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Obligations><Obligation ObligationId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Obligation></Obligations></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + + @Test + public void testAdvice() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableAdvice Advice; + + // test Advice single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Advice missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + null)); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing Required DataType (Different than JSON where DataType is optional with default String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Lisa</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#string\">Maggie</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 1111))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 2222))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 3333))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">1111</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">2222</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"http://www.w3.org/2001/XMLSchema#integer\">3333</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><AssociatedAdvice><Advice AdviceId=\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:record</AttributeAssignment><AttributeAssignment AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject\" DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" xmlns:md=\"referenceForMD\" xmlns=\"defaultURI\">//md:hospital</AttributeAssignment></Advice></AssociatedAdvice></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + + + + + + + // Attributes tests + @Test + public void testAttributes() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + + + Identifier categoryIdentifier; + List<Attribute> attrList = new ArrayList<Attribute>(); + StdMutableAttribute mutableAttribute; + + // Attr list with no entries + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // multiple attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // IncludeInResult=false/true + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", false)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Missing AttributeId (mandatory) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, null, new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Missing mandatory Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), null), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // Missing optional Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // missing required DataType (different from JSON where DataType is optional and assumed to be String) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(null, "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // same id, same type different issuer + // (This is not an array of values because Issuer is different) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "CIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same id, same type same issuer + // (This is an array of values) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Simpson</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, different issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // different Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "AIssue"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent2\" Issuer=\"BIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">AIssue</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute of type XPathExpression (the only complex data type) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategory")), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\" XPathCategory=\"xpathCategory\">//md:record</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // multiple sets of values + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent3\" Issuer=\"CIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent4\" Issuer=\"DIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent5\" Issuer=\"EIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrNoIssuer\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes><Attributes Category=\"secondCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent12\" Issuer=\"AIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu2</AttributeValue></Attribute><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent32\" Issuer=\"CIssue2\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Der2</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - same type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned")); + + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Bart</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Homer</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Ned</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - compatible different types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - incompatible different types (Different from JSON because these are not part of an array in XML, just separate values) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M")); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + mutableAttribute.addValue(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), 4567)); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><Attributes Category=\"firstCategory\"><Attribute IncludeInResult=\"true\" AttributeId=\"attrIdent1\" Issuer=\"AIssue\"><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Apu</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\">P10Y4M</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#double\">765.432</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#boolean\">true</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue><AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#integer\">4567</AttributeValue></Attribute></Attributes></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + + + // PolicyIdentifier tests + @Test + public void testPolicyIdentifier() { + + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + + // multiple PolicyIdentifiers of both types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // PolicyIdentifier exists but has no IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policyIdentifier1 = null; + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // PolicySetIdentifier exists but has not IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policySetIdentifier1 = null; + result.addPolicyIdentifier(policySetIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (DOMStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from object to XML: " + e); + } + + // PolicyIdentifier with PolicyIdReference and no PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference Version=\"1.2.3\">idRef1</PolicyIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // PolicyIdentifier with no PolicyIdReference and with PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicySetIdentifier(policySetIdentifier1); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicySetIdReference Version=\"4.5.6.7.8.9.0\">idSetRef1</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // IdReferences without version + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), null); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + xmlResponse = DOMResponse.toString(response, false); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"><Result><Decision>Permit</Decision><PolicyIdentifierList><PolicyIdReference>idRef1</PolicyIdReference><PolicyIdReference>idRef2_NoVersion</PolicyIdReference><PolicySetIdReference>idSetRef1</PolicySetIdReference><PolicySetIdReference>idSetRef2_NoVersion</PolicySetIdReference></PolicyIdentifierList></Result></Response>", xmlResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + +//TODO - the XML spec implies that the Result Attributes may include the Content (It is part of the UML) + + + // test indentation??? + + +} + + +/* +Place to edit long strings ouput from tests + + +Expected +<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response> +<?xml version="1.0" encoding="UTF-8"?><Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"><Result><Decision>Permit</Decision></Result></Response> +Actual + + + + */ + + + + + + + + + + + + + diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestAnnotation.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestAnnotation.java new file mode 100644 index 000000000..c5dda8a91 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestAnnotation.java @@ -0,0 +1,239 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.TimeZone; + +import org.apache.commons.cli.ParseException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.std.annotations.RequestParser; +import com.att.research.xacml.std.annotations.XACMLAction; +import com.att.research.xacml.std.annotations.XACMLAttribute; +import com.att.research.xacml.std.annotations.XACMLEnvironment; +import com.att.research.xacml.std.annotations.XACMLMultiRequest; +import com.att.research.xacml.std.annotations.XACMLRequest; +import com.att.research.xacml.std.annotations.XACMLRequestReference; +import com.att.research.xacml.std.annotations.XACMLResource; +import com.att.research.xacml.std.annotations.XACMLSubject; +import com.att.research.xacml.std.datatypes.HexBinary; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.IPv4Address; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.util.FactoryException; + +/** + * This example application shows how to use annotations for Java classes to create requests to send to the + * engine. + * + * + */ +public class TestAnnotation extends TestBase { + private static final Log logger = LogFactory.getLog(TestAnnotation.class); + + private int num; + + /** + * This is a sample class that uses annotations. In addition to demonstrating how to use XACML annotations, + * it also demonstrates the various Java objects that can be used and how the request parser will + * resolve each object's datatype. + * + * + */ + @XACMLRequest(ReturnPolicyIdList=true) + public class MyRequestAttributes { + + public MyRequestAttributes(String user, String action, String resource) { + this.userID = user; + this.action = action; + this.resource = resource; + this.today = new Date(); + this.yesterday = Calendar.getInstance(); + this.yesterday.add(Calendar.DAY_OF_MONTH, -1); + } + + @XACMLSubject(includeInResults=true) + String userID; + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id-qualifier") + boolean admin = false; + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:key-info", issuer="com:foo:security") + HexBinary publicKey = new HexBinary(new byte[] {'1', '0'}); + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:authentication-time") + ISO8601Time authenticationTime = new ISO8601Time(8, 0, 0, 0); + + /** + * Here our base object is "Object", but it is reflected as a Java "String". The parser + * will then use the XACML http://www.w3.org/2001/XMLSchema#string as the datatype. + */ + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:authentication-method") + Object authenticationMethod = new String("RSA Public Key"); + + /** + * Here our base object is "String", but we use the annotation for datatype to clarify + * that the real XACML data type is http://www.w3.org/2001/XMLSchema#time. The parser will + * use the data type factory to convert the "String" to a "ISO8601Time" Java object. + */ + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:request-time", datatype="http://www.w3.org/2001/XMLSchema#time") + String requestTime = new String("13:20:00-05:00"); + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:1.0:subject:session-start-time") + ISO8601DateTime sessionStart = new ISO8601DateTime(TimeZone.getDefault().getID(), 2014, 1, 1, 10, 0, 0, 0); + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:3.0:subject:authn-locality:ip-address") + IPAddress ip = new IPv4Address(new short[] {123, 134, 156, 255 }, null, null); + + @XACMLSubject(attributeId="urn:oasis:names:tc:xacml:3.0:subject:authn-locality:dns-name") + String dnsName = "localhost"; + + @XACMLAction() + String action; + + @XACMLAction(attributeId="urn:oasis:names:tc:xacml:1.0:action:implied-action") + long impliedAction; + + @XACMLResource() + String resource; + + @XACMLEnvironment() + Date today; + + @XACMLEnvironment() + Calendar yesterday; + + /** + * This field demonstrates how the parser can detect collections and build a bag of values. + */ + @XACMLAttribute(attributeId="foo:bar:attribute") + Collection<Double> fooBar = Arrays.asList(2.5, 3.5); + + /** + * The XACMLAttribute annotation allows one to specify all the + */ + @XACMLAttribute(category="foo:bar:category", attributeId="foo:bar:attribute2") + double fooBar2 = 3.999; + + /** + * This field demonstrates how the parser can detect arrays and build a bag of values. + */ + @XACMLAttribute(category="foo:bar:category", attributeId="foo:bar:attribute:many") + URI[] fooBarMany = new URI[] {URI.create("file://opt/app/test"), URI.create("https://localhost:8443/")}; + + }; + + @XACMLRequest( + Defaults="http://www.w3.org/TR/1999/Rec-xpath-19991116", + multiRequest=@XACMLMultiRequest(values={ + @XACMLRequestReference(values={"subject1", "action", "resource"}), + @XACMLRequestReference(values={"subject2", "action", "resource"})}) + ) + public class MyMultiRequestAttributes { + + @XACMLSubject(id="subject1") + String userID1 = "John"; + + @XACMLSubject(id="subject2") + String userID2 = "Ringo"; + + @XACMLAction(id="action") + String action = "access"; + + @XACMLResource(id="resource") + String resource = "www.mywebsite.com"; + } + + public TestAnnotation(String[] args) throws MalformedURLException, ParseException, HelpException { + super(args); + } + + @Override + public void run() throws IOException, FactoryException { + // + // We are not going to iterate any existing request files. So we will override + // any TestBase code that assumes there are request files present. + // + // + // Configure ourselves + // + this.configure(); + // + // Cycle through creating a few objects + // + this.num = 0; + this.doRequest(new MyRequestAttributes("John", "access", "www.mywebsite.com")); + this.num++; + this.doRequest(new MyRequestAttributes("Ringo", "access", "www.mywebsite.com")); + this.num++; + this.doRequest(new MyMultiRequestAttributes()); + this.num++; + } + + private void doRequest(Object info) { + try { + Response response = this.callPDP(RequestParser.parseRequest(info)); + Path resultFile; + if (this.output != null) { + resultFile = Paths.get(this.output.toString(), "Response." + String.format("%03d", this.num) + ".json"); + } else { + resultFile = Paths.get(this.directory, "results", "Response." + String.format("%03d", this.num) + ".json"); + } + // + // Write the response to the result file + // + logger.info("Response is: " + response.toString()); + if (resultFile != null) { + Files.write(resultFile, response.toString().getBytes()); + } + } catch (IllegalArgumentException | IllegalAccessException | DataTypeException | IOException e) { + logger.error(e); + e.printStackTrace(); + } + } + + public static void main(String[] args) { + try { + new TestAnnotation(args).run(); + } catch (ParseException | IOException | FactoryException e) { + logger.error(e); + } catch (HelpException e) { + // + // ignore this, its thrown just to exit the application + // after dumping help to stdout. + // + } + } +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestBase.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestBase.java new file mode 100644 index 000000000..8f757ab59 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestBase.java @@ -0,0 +1,1082 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.entity.ContentType; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.DataType; +import com.att.research.xacml.api.DataTypeException; +import com.att.research.xacml.api.DataTypeFactory; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.api.pdp.PDPException; +import com.att.research.xacml.api.pep.PEPException; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttributeValue; +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.DOMRequest; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.dom.DOMStructureException; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.std.json.JSONStructureException; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + +/** + * This is a base class for setting up a test environment. Using properties files, it contains the + * necessary information for + * 1. defining and providing attributes + * 2. defining and instantiating the PDP engine + * 3. creating PEP requests and calling the PDP engine + * + * + */ +public class TestBase extends SimpleFileVisitor<Path> { + private static final Log logger = LogFactory.getLog(TestBase.class); + + public class HelpException extends Exception { + private static final long serialVersionUID = 1L; + + } + + /** + * This private class holds information for properties defined for attribute + * generation. The user can configure the properties file such that attributes + * can be automatically generated and added into each request. + * + * + */ + class Generator { + Path file; + InputStream is; + BufferedReader reader; + List<StdMutableAttribute> attributes = new ArrayList<StdMutableAttribute>(); + + public Generator(Path path) { + this.file = path; + } + + /** + * read - reads in the next line of data + * + * @return String - a line from the csv containing attribute data + */ + public String read() { + String str = null; + if (is == null) { + try { + is = Files.newInputStream(file); + } catch (IOException e) { + logger.error(e); + return null; + } + } + if (reader == null) { + reader = new BufferedReader(new InputStreamReader(this.is)); + } + try { + str = reader.readLine(); + if (str == null) { + // + // No more strings, close up + // + this.close(); + } + if (logger.isDebugEnabled()) { + logger.debug(str); + } + } catch (IOException e) { + logger.error(e); + } + return str; + } + + public void close() { + if (this.reader != null) { + try { + this.reader.close(); + } catch (IOException idontcare) { + } finally { + this.reader = null; + this.is = null; + } + } + } + + } + + public static final String PROP_GENERATOR = "xacml.attribute.generator"; + + public static final String OPTION_HELP = "help"; + public static final String OPTION_TESTDIR = "dir"; + public static final String OPTION_TESTREST = "rest"; + public static final String OPTION_TESTURL = "url"; + public static final String OPTION_TESTOUTPUT = "output"; + public static final String OPTION_LOOP = "loop"; + public static final String OPTION_TESTNUMBERS = "testNumbers"; + + public static final String DEFAULT_RESTURL = "https://localhost:8080/pdp/"; // Modified for test purpose. Port no. 8443 to 8080 + + public static Options options = new Options(); + static { + options.addOption(new Option(OPTION_HELP, false, "Prints help.")); + options.addOption(new Option(OPTION_TESTDIR, true, "Directory path where all the test properties and data are located.")); + options.addOption(new Option(OPTION_TESTREST, false, "Test against RESTful PDP.")); + options.addOption(new Option(OPTION_TESTURL, true, "URL to the RESTful PDP. Default is " + DEFAULT_RESTURL)); + options.addOption(new Option(OPTION_TESTOUTPUT, true, "Specify a different location for dumping responses.")); + options.addOption(new Option(OPTION_LOOP, true, "Number of times to loop through the tests. Default is 1. A value of -1 runs indefinitely.")); + options.addOption(new Option(OPTION_TESTNUMBERS, true, "Comma-separated list of numbers found in the names of the test files to be run. Numbers must exactly match the file name, e.g. '02'. Used to limit testing to specific set of tests.")); + } + + protected String directory = null; + protected Path output = null; + protected boolean isREST; + protected URL restURL = null; + protected int loop = 1; + protected PDPEngine engine = null; + protected List<Generator> generators = new ArrayList<Generator>(); + protected static DataTypeFactory dataTypeFactory = null; + + private long permits = 0; + private long denies = 0; + private long notapplicables = 0; + private long indeterminates = 0; + + private long expectedPermits = 0; + private long expectedDenies = 0; + private long expectedNotApplicables = 0; + private long expectedIndeterminates = 0; + + private long generatedpermits = 0; + private long generateddenies = 0; + private long generatednotapplicables = 0; + private long generatedindeterminates = 0; + + private long responseMatches = 0; + private long responseNotMatches = 0; + + private String[] testNumbersArray = null; + + protected final Pattern pattern = Pattern.compile("Request[.]\\d+[.](Permit|Deny|NA|Indeterminate|Generate|Unknown)\\.(json|xml)"); + + public static boolean isJSON(Path file) { + return file.toString().endsWith(".json"); + } + + public static boolean isXML(Path file) { + return file.toString().endsWith(".xml"); + } + + public TestBase(String[] args) throws ParseException, MalformedURLException, HelpException { + // + // Finish Initialization + // + this.restURL = new URL(DEFAULT_RESTURL); + // + // Parse arguments + // + this.parseCommands(args); + } + + /** + * Parse in the command line arguments that the following parameters: + * + * @param args - command line arguments + * @throws ParseException + * @throws MalformedURLException + * @throws HelpException + */ + protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException { + // + // Parse the command line options + // + CommandLine cl; + cl = new GnuParser().parse(options, args); + // + // Check for what we have + // + if (cl.hasOption(OPTION_HELP)) { + new HelpFormatter().printHelp("Usage: -dir testdirectory OPTIONS", + options); + throw new HelpException(); + } + if (cl.hasOption(OPTION_TESTDIR)) { + this.directory = cl.getOptionValue(OPTION_TESTDIR); + } else { + throw new IllegalArgumentException("You must specify a test directory. -dir path/to/some/where"); + } + if (cl.hasOption(OPTION_TESTREST)) { + this.isREST = true; + } else { + this.isREST = false; + } + if (cl.hasOption(OPTION_TESTURL)) { + this.restURL = new URL(cl.getOptionValue(OPTION_TESTURL)); + } + if (cl.hasOption(OPTION_TESTOUTPUT)) { + this.output = Paths.get(cl.getOptionValue(OPTION_TESTOUTPUT)); + } else { + this.output = Paths.get(this.directory, "results"); + } + if (cl.hasOption(OPTION_LOOP)) { + this.loop = Integer.parseInt(cl.getOptionValue(OPTION_LOOP)); + } + if (cl.hasOption(OPTION_TESTNUMBERS)) { + String testNumberString = cl.getOptionValue(OPTION_TESTNUMBERS); + testNumbersArray = testNumberString.split(","); + // + // reset strings to include dots so they exactly match pattern in file name + // + for (int i = 0; i < testNumbersArray.length; i++) { + testNumbersArray[i] = "." + testNumbersArray[i] + "."; + } + } + } + + /** + * Using the command line options that were parsed, configures our test instance. + * + * @throws FactoryException + */ + protected void configure() throws FactoryException { + // + // Setup the xacml.properties file + // + if (this.directory == null) { + throw new IllegalArgumentException("Must supply a path to a test directory."); + } + Path pathDir = Paths.get(this.directory, "xacml.properties"); + if (Files.notExists(pathDir)) { + throw new IllegalArgumentException(pathDir.toString() + " does not exist."); + } + // + // Set it as the System variable so the XACML factories know where the properties are + // loaded from. + // + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, pathDir.toString()); + // + // Now we can create the data type factory + // + dataTypeFactory = DataTypeFactory.newInstance(); + // + // Load in what generators we are to create + // + String generators = XACMLProperties.getProperty(PROP_GENERATOR); + if (generators != null) { + // + // Parse the generators + // + for (String generator : Splitter.on(',').trimResults().omitEmptyStrings().split(generators)) { + this.configureGenerator(generator); + } + } + // + // If we are embedded, create our engine + // + if (this.isREST == false) { + PDPEngineFactory factory = PDPEngineFactory.newInstance(); + this.engine = factory.newEngine(); + } + // + // Remove all the responses from the results directory + // + this.removeResults(); + } + + /** + * Removes all the Response* files from the results directory. + * + */ + public void removeResults() { + try { + // + // Determine where the results are supposed to be written to + // + Path resultsPath; + if (this.output != null) { + resultsPath = this.output; + } else { + resultsPath = Paths.get(this.directory.toString(), "results"); + } + // + // Walk the files + // + Files.walkFileTree(resultsPath, new SimpleFileVisitor<Path>() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getFileName().toString().startsWith("Response")) { + Files.delete(file); + } + return super.visitFile(file, attrs); + } + }); + } catch (IOException e) { + logger.error("Failed to removeRequests from " + this.directory + " " + e); + } + } + + /** + * Configure's a specific generator instance from the properties file. + * + * @param generator + */ + protected void configureGenerator(String generator) { + String prefix = PROP_GENERATOR + "." + generator; + String file = XACMLProperties.getProperty(prefix + ".file"); + // + // Create a generator object + // + Generator gen = new Generator(Paths.get(this.directory, file)); + this.generators.add(gen); + // + // Grab attributes + // + String attributes = XACMLProperties.getProperty(prefix + ".attributes"); + for (String attribute : Splitter.on(',').trimResults().omitEmptyStrings().split(attributes)) { + String attributePrefix = prefix + ".attributes." + attribute; + // + // Create an attribute value. It is simply a placeholder for the field within + // the CSV that contains the actual attribute value. It mainly holds the data type + // + Identifier datatype = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".datatype")); + Integer field = Integer.parseInt(XACMLProperties.getProperty(attributePrefix + ".field")); + StdAttributeValue<?> value = new StdAttributeValue<>(datatype, field); + // + // Get the rest of the attribute properties + // + Identifier category = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".category")); + Identifier id = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".id")); + String issuer = XACMLProperties.getProperty(attributePrefix + ".issuer"); + boolean include = Boolean.parseBoolean(XACMLProperties.getProperty(attributePrefix + ".include", "false")); + // + // Now we have a skeleton attribute + // + gen.attributes.add(new StdMutableAttribute(category, id, value, issuer, include)); + } + } + + /** + * This runs() the test instance. It first configure's itself and then walks the + * requests directory issue each request to the PDP engine. + * + * @throws IOException + * @throws FactoryException + * + */ + public void run() throws IOException, FactoryException { + // + // Configure ourselves + // + this.configure(); + // + // Loop and run + // + int runs = 1; + do { + long lTimeStart = System.currentTimeMillis(); + logger.info("Run number: " + runs); + // + // Walk the request directory + // + Files.walkFileTree(Paths.get(this.directory.toString(), "requests"), this); + long lTimeEnd = System.currentTimeMillis(); + logger.info("Run elapsed time: " + (lTimeEnd - lTimeStart) + "ms"); + // + // Dump the stats + // + this.dumpStats(); + this.resetStats(); + // + // Increment + // + runs++; + } while ((this.loop == -1 ? true : runs <= this.loop)); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + // + // Sanity check the file name + // + Matcher matcher = this.pattern.matcher(file.getFileName().toString()); + if (matcher.matches()) { + // + // if user has limited which files to use, check that here + // + if (testNumbersArray != null) { + String fileNameString = file.getFileName().toString(); + boolean found = false; + for (String numberString : testNumbersArray) { + if (fileNameString.contains(numberString)) { + found = true; + break; + } + } + if (found == false) { + // + // this test is not in the list to be run, so skip it + // + return super.visitFile(file, attrs); + } + } + try { + // + // Pull what this request is supposed to be + // + String group = null; + int count = matcher.groupCount(); + if (count >= 1) { + group = matcher.group(count-1); + } + // + // Send it + // + this.sendRequest(file, group); + } catch (Exception e) { + logger.error(e); + e.printStackTrace(); + } + } + return super.visitFile(file, attrs); + } + + /** + * When a request file is encountered, this method is called send the request to the PDP engine. It will also dump + * the response object. If the group equals "Generate", then it will loop and send the request with generated attributes + * until that list is empty. + * + * @param file - Request file. Eg. Request-01-Permit.json + * @param group - This is the parsed out string of the request file that defines if it is a Permit/Deny/Generate etc. + * @throws Exception + */ + protected void sendRequest(Path file, String group) throws Exception { + logger.info(file.toString()); + int requestCount = 0; + do { + // + // Generate the request + // + Request request = this.generateRequest(file, group); + // + // Was something generated? + // + if (request == null) { + // + // Get out of the loop + // + logger.info("NULL request generated."); + break; + } + logger.info(request); + // + // Call the PDP + // + Response response = this.callPDP(request); + // + // Process the response + // + this.processResponse(file, request, response, group, requestCount); + // + // Is this a generated request? + // + if (group.equals("Generate")) { + // + // Yes, increment counter and move + // on to the next generated request. + // + requestCount++; + } else { + // + // Nope, exit the loop + // + break; + } + } while (group.equals("Generate")); + } + + /** + * Sends the request object to the PDP engine. Either the embedded engine or the RESTful engine. + * + * @param request - XACML request object + * @return Response - returns the XACML response object + */ + protected Response callPDP(Request request) { + // + // Send it to the PDP + // + Response response = null; + if (this.isREST) { + try { + String jsonString = JSONRequest.toString(request, false); + // + // Call RESTful PDP + // + response = this.callRESTfulPDP(new ByteArrayInputStream(jsonString.getBytes())); + } catch (Exception e) { + logger.error("Error in sending RESTful request: " + e, e); + } + } else { + // + // Embedded call to PDP + // + long lTimeStart = System.currentTimeMillis(); + try { + response = this.engine.decide(request); + } catch (PDPException e) { + logger.error(e); + } + long lTimeEnd = System.currentTimeMillis(); + logger.info("Elapsed Time: " + (lTimeEnd - lTimeStart) + "ms"); + } + return response; + } + + /** + * Reads the request file into a Request object based on its type. + * + * If the request has "Generate" in its filename, then this function will add + * generated attributes into the request. + * + * @param file - Request file. Eg. Request-01-Permit.json + * @param group - This is the parsed out string of the request file that defines if it is a Permit/Deny/Generate etc. + * @return + * @throws JSONStructureException + * @throws DOMStructureException + * @throws PEPException + */ + protected Request generateRequest(Path file, String group) throws JSONStructureException, DOMStructureException, PEPException { + // + // Convert to a XACML Request Object + // + Request request = null; + if (TestBase.isJSON(file)) { + request = JSONRequest.load(file.toFile()); + } else if (TestBase.isXML(file)) { + request = DOMRequest.load(file.toFile()); + } + if (request == null) { + throw new PEPException("Invalid Request File: " + file.toString()); + } + // + // Only if this request has "Generate" + // Request.XX.Generate.[json|xml] + // + if (group.equals("Generate")) { + // + // Add attributes to it + // + request = this.onNextRequest(request); + } + // + // Done + // + return request; + } + + /** + * Called to add in generated attributes into the request. + * + * @param request + * @return + */ + protected Request onNextRequest(Request request) { + // + // If we have no generators, just return + // + if (this.generators.isEmpty()) { + return request; + } + // + // Copy the request attributes + // + List<StdMutableRequestAttributes> attributes = new ArrayList<StdMutableRequestAttributes>(); + for (RequestAttributes a : request.getRequestAttributes()) { + attributes.add(new StdMutableRequestAttributes(a)); + } + // + // Iterate the generators + // + for (Generator generator : this.generators) { + // + // Read a row in + // + String line = generator.read(); + // + // Was something read? + // + if (line == null) { + // + // No more rows to read, return null + // + return null; + } + // + // Split the line + // + List<String> fields = Lists.newArrayList(Splitter.on(',').trimResults().split(line)); + // + // Now work on the attributes + // + for (StdMutableAttribute attribute : generator.attributes) { + // + // Grab the attribute holder, which holds the datatype and field. There should + // be only ONE object in the collection. + // + AttributeValue<?> value = attribute.getValues().iterator().next(); + Integer field = (Integer) value.getValue(); + // + // Is the field number valid? + // + if (field >= fields.size()) { + logger.error("Not enough fields: " + field + "(" + fields.size() + ")"); + return null; + } + // + // Determine what datatype it is + // + DataType<?> dataTypeExtended = dataTypeFactory.getDataType(value.getDataTypeId()); + if (dataTypeExtended == null) { + logger.error("Failed to determine datatype"); + return null; + } + // + // Create the attribute value + // + try { + AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(fields.get(field)); + // + // Create the attribute + // + StdMutableAttribute newAttribute = new StdMutableAttribute(attribute.getCategory(), + attribute.getAttributeId(), + attributeValue, + attribute.getIssuer(), + attribute.getIncludeInResults()); + boolean added = false; + for (StdMutableRequestAttributes a : attributes) { + // + // Does the category exist? + // + if (a.getCategory().equals(attribute.getCategory())) { + // + // 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(request.getCombinedDecision()); + newRequest.setRequestDefaults(request.getRequestDefaults()); + newRequest.setReturnPolicyIdList(request.getReturnPolicyIdList()); + newRequest.setStatus(request.getStatus()); + for (StdMutableRequestAttributes a : attributes) { + newRequest.add(a); + } + return newRequest; + } + + /** + * This makes an HTTP POST call to a running PDP RESTful servlet to get a decision. + * + * @param file + * @return + */ + protected Response callRESTfulPDP(InputStream is) { + Response response = null; + HttpURLConnection connection = null; + try { + + // + // Open up the connection + // + connection = (HttpURLConnection) this.restURL.openConnection(); + connection.setRequestProperty("Content-Type", "application/json"); + // + // Setup our method and headers + // + connection.setRequestMethod("POST"); + connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + // + // Send the request + // + try (OutputStream os = connection.getOutputStream()) { + IOUtils.copy(is, os); + } + // + // Do the connect + // + connection.connect(); + if (connection.getResponseCode() == 200) { + // + // Read the response + // + ContentType contentType = null; + try { + contentType = ContentType.parse(connection.getContentType()); + + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + response = JSONResponse.load(connection.getInputStream()); + } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML.getMimeType()) || + contentType.getMimeType().equalsIgnoreCase("application/xacml+xml") ) { + response = DOMResponse.load(connection.getInputStream()); + } else { + logger.error("unknown content-type: " + contentType); + } + + } catch (Exception e) { + String message = "Parsing Content-Type: " + connection.getContentType() + ", error=" + e.getMessage(); + logger.error(message, e); + } + + } else { + logger.error(connection.getResponseCode() + " " + connection.getResponseMessage()); + } + } catch (Exception e) { + logger.error(e); + } + + return response; + } + + /** + * This processes a response. Saves the response out to disk. If there is a corresponding response file for the request located + * in the "responses" sub-directory, then this method will compare that response file with what the engine returned to see if it + * matched. + * + * @param requestFile + * @param request + * @param response + * @param group + * @param count + * @throws Exception + */ + protected void processResponse(Path requestFile, Request request, Response response, String group, int count) throws Exception { + // + // Construct the output filename + // + Path responseFile = null; + Path resultFile = null; + int num = requestFile.getNameCount(); + if (num < 2) { + logger.error("Too few dir's in request filename."); + throw new Exception("Too few dir's in request filename. Format should be Request.[0-9]+.{Permit|Deny|NA|Indeterminate}.{json|xml}"); + } + String filename = requestFile.getFileName().toString(); + if (group.equals("Generate")) { + // + // Using count variable, construct a filename + // + // i.e. Response.03.Generate.{count}.json + // + filename = "Response" + filename.substring(filename.indexOf('.'), filename.lastIndexOf('.')) + String.format("%03d", count) + filename.substring(filename.lastIndexOf('.')); + } else { + // + // Construct filename + // + filename = "Response" + filename.substring(filename.indexOf('.')); + } + // + // Determine equivalent response file path + // + responseFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "responses"); + if (Files.notExists(responseFile)) { + // + // Create it + // + logger.warn(responseFile.toString() + " does NOT exist, creating..."); + try { + Files.createDirectories(responseFile); + } catch (IOException e) { + logger.error(e); + throw new Exception("Cannot proceed without an output directory."); + } + } + responseFile = Paths.get(responseFile.toString(), filename); + // + // Determine path to write result file + // + if (this.output != null) { + // + // User specified an output path + // + resultFile = this.output; + } else { + // + // Default path + // + resultFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "results"); + } + // + // Check if the path exists + // + if (Files.notExists(resultFile)) { + // + // Create it + // + logger.warn(resultFile.toString() + " does NOT exist, creating..."); + try { + Files.createDirectories(resultFile); + } catch (IOException e) { + logger.error(e); + throw new Exception("Cannot proceed without an output directory."); + } + } + // + // Add the filename to the path + // + resultFile = Paths.get(resultFile.toString(), filename); + // + // Check if there is an equivalent response in the response + // directory. If so, compare our response result with that one. + // + boolean succeeded = true; + if (responseFile != null && Files.exists(responseFile)) { + // + // Do comparison + // + Response expectedResponse = null; + if (TestBase.isJSON(responseFile)) { + expectedResponse = JSONResponse.load(responseFile); + } else if (TestBase.isXML(responseFile)) { + expectedResponse = DOMResponse.load(responseFile); + } + if (expectedResponse != null) { + // + // Do the compare + // + if (response == null) { + logger.error("NULL response returned."); + this.responseNotMatches++; + succeeded = false; + } else { + if (response.equals(expectedResponse)) { + logger.info("Response matches expected response."); + this.responseMatches++; + } else { + logger.error("Response does not match expected response."); + logger.error("Expected: "); + logger.error(expectedResponse.toString()); + this.responseNotMatches++; + succeeded = false; + } + } + } + } + // + // Write the response to the result file + // + logger.info("Request: " + requestFile.getFileName() + " response is: " + (response == null ? "null" : response.toString())); + if (resultFile != null && response != null) { + if (TestBase.isJSON(resultFile)) { + Files.write(resultFile, JSONResponse.toString(response, true).getBytes()); + } else if (TestBase.isXML(resultFile)) { + Files.write(resultFile, DOMResponse.toString(response, true).getBytes()); + } + } + // + // Stats + // + if (group.equals("Permit")) { + this.expectedPermits++; + } else if (group.equals("Deny")) { + this.expectedDenies++; + } else if (group.equals("NA")) { + this.expectedNotApplicables++; + } else if (group.equals("Indeterminate")) { + this.expectedIndeterminates++; + } + if (response != null) { + for (Result result : response.getResults()) { + Decision decision = result.getDecision(); + if (group.equals("Generate")) { + if (decision.equals(Decision.PERMIT)) { + this.generatedpermits++; + } else if (decision.equals(Decision.DENY)) { + this.generateddenies++; + } else if (decision.equals(Decision.NOTAPPLICABLE)) { + this.generatednotapplicables++; + } else if (decision.equals(Decision.INDETERMINATE)) { + this.generatedindeterminates++; + } + continue; + } + if (decision.equals(Decision.PERMIT)) { + this.permits++; + if (group.equals("Permit") == false) { + succeeded = false; + logger.error("Expected " + group + " got " + decision); + } + } else if (decision.equals(Decision.DENY)) { + this.denies++; + if (group.equals("Deny") == false) { + succeeded = false; + logger.error("Expected " + group + " got " + decision); + } + } else if (decision.equals(Decision.NOTAPPLICABLE)) { + this.notapplicables++; + if (group.equals("NA") == false) { + succeeded = false; + logger.error("Expected " + group + " got " + decision); + } + } else if (decision.equals(Decision.INDETERMINATE)) { + this.indeterminates++; + if (group.equals("Indeterminate") == false) { + succeeded = false; + logger.error("Expected " + group + " got " + decision); + } + } + } + } + if (succeeded) { + logger.info("REQUEST SUCCEEDED"); + } else { + logger.info("REQUEST FAILED"); + } + } + + protected void dumpStats() { + StringBuilder dump = new StringBuilder(); + dump.append(System.lineSeparator()); + dump.append("Permits: " + this.permits + " Expected: " + this.expectedPermits); + dump.append(System.lineSeparator()); + dump.append("Denies: " + this.denies + " Expected: " + this.expectedDenies); + dump.append(System.lineSeparator()); + dump.append("NA: " + this.notapplicables + " Expected: " + this.expectedNotApplicables); + dump.append(System.lineSeparator()); + dump.append("Indeterminates: " + this.indeterminates + " Expected: " + this.expectedIndeterminates); + dump.append(System.lineSeparator()); + dump.append("Generated Permits: " + this.generatedpermits); + dump.append(System.lineSeparator()); + dump.append("Generated Denies: " + this.generateddenies); + dump.append(System.lineSeparator()); + dump.append("Generated NA: " + this.generatednotapplicables); + dump.append(System.lineSeparator()); + dump.append("Generated Indeterminates: " + this.generatedindeterminates); + dump.append(System.lineSeparator()); + dump.append("Responses Matched: " + this.responseMatches); + dump.append(System.lineSeparator()); + dump.append("Responses NOT Matched: " + this.responseNotMatches); + + if (this.permits != this.expectedPermits || + this.denies != this.expectedDenies || + this.notapplicables != this.expectedNotApplicables || + this.indeterminates != this.expectedIndeterminates || + this.responseNotMatches > 0) { + logger.fatal(dump.toString()); + } else { + logger.info(dump.toString()); + } + } + + protected void resetStats() { + this.permits = 0; + this.denies = 0; + this.notapplicables = 0; + this.indeterminates = 0; + this.generatedpermits = 0; + this.generateddenies = 0; + this.generatednotapplicables = 0; + this.generatedindeterminates = 0; + this.responseMatches = 0; + this.responseNotMatches = 0; + } + + public static void main(String[] args) { + try { + new TestBase(args).run(); + } catch (ParseException | IOException | FactoryException e) { + logger.error(e); + } catch (HelpException e) { + } + } +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java new file mode 100644 index 000000000..983855900 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java @@ -0,0 +1,792 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.Marshaller; + +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributesType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.RequestType; + +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.DataTypeFactory; +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.util.FactoryException; +import com.att.research.xacml.util.XACMLObjectCopy; +import com.att.research.xacml.util.XACMLPolicyAggregator; +import com.att.research.xacml.util.XACMLPolicyScanner; +import com.att.research.xacml.util.XACMLProperties; + +/** + * This class reads the policy in and extracts all the attributes and their values that is contained + * in the Policy. It then generates a request every single combination of attributes found. + * + * The attributes mostly come from the Target Match elements, since they have both an attribute designator/selector + * matched with an attribute value. + * + * + */ +public class TestPolicy extends TestBase { + private static Log logger = LogFactory.getLog(TestPolicy.class); + + private boolean skip; + private Path policy; + private XACMLPolicyAggregator aggregator = new XACMLPolicyAggregator(); + private long index; + + // + // Our command line parameters + // + public static final String OPTION_POLICY = "policy"; + public static final String OPTION_SKIP_GENERATE = "skip"; + + static { + options.addOption(new Option(OPTION_POLICY, true, "Path to the policy file.")); + options.addOption(new Option(OPTION_SKIP_GENERATE, false, "Skip generating requests.")); + } + + public class FlattenerObject { + Identifier category; + Identifier datatype; + Identifier attribute; + Set<AttributeValue<?>> values; + } + + /** + * This application exercises a policy by producing ALL the possible request combinations for a policy. + * + * -policy Path to a policy file + * + * @param args + * @throws HelpException + * @throws ParseException + * @throws MalformedURLException + */ + + public TestPolicy(String[] args) throws MalformedURLException, ParseException, HelpException { + super(args); + } + + /* + * Look for the -policy command line argument. This application needs a pointer to a specific policy + * in order to run. + * + * + * (non-Javadoc) + * @see com.att.research.xacmlatt.pdp.test.TestBase#parseCommands(java.lang.String[]) + */ + @Override + protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException { + // + // Have our super do its job + // + super.parseCommands(args); + // + // Look for the policy option + // + CommandLine cl; + cl = new GnuParser().parse(options, args); + if (cl.hasOption(OPTION_POLICY)) { + this.policy = Paths.get(cl.getOptionValue(OPTION_POLICY)); + // + // Ensure it exists + // + if (Files.notExists(this.policy)) { + throw new ParseException("Policy file does not exist."); + } + } else { + throw new ParseException("You need to specify the policy file to be used."); + } + if (cl.hasOption(OPTION_SKIP_GENERATE)) { + this.skip = true; + } else { + this.skip = false; + } + } + + /* + * We override this method because here is where we want to scan the policy and aggregate all + * the attributes that are defined within the policy. This routine will then dump all the possible + * requests into the requests sub-directory. Thus, when this method returns the TestBase can proceed + * to iterate each generated request and run it against the PDP engine. + * + * (non-Javadoc) + * @see com.att.research.xacmlatt.pdp.test.TestBase#configure() + */ + @Override + protected void configure() throws FactoryException { + // + // Have our base class do its thing + // + super.configure(); + // + // Setup where the PDP can find the policy + // + System.setProperty(XACMLProperties.PROP_ROOTPOLICIES, "policy"); + System.setProperty("policy.file", this.policy.toString()); + // + // Determine if they want us to skip generation. This helps when a huge number of + // requests will get generated for a policy and can take some time to do so. The user + // can generate the requests once and then start testing a policy against the requests. Thus, + // the attributes never changed but the policy logic did (saves time). + // + if (this.skip) { + return; + } + // + // Now we will scan the policy and get all the attributes. + // + XACMLPolicyScanner scanner = new XACMLPolicyScanner(this.policy, this.aggregator); + // + // The scanner returns us a policy object + // + Object policyObject = scanner.scan(); + // + // Just dump some info + // + if (policyObject instanceof PolicySetType) { + logger.info("Creating requests for policyset: " + ((PolicySetType)policyObject).getDescription()); + } else if (policyObject instanceof PolicyType) { + logger.info("Creating requests for policy: " + ((PolicyType)policyObject).getDescription()); + } + // + // Call the function to create the requests + // + if (policyObject != null) { + this.createRequests(); + } + + logger.info("Completed Generating requests."); + } + + @SuppressWarnings("unchecked") + protected void createRequests() { + // + // Clear out our request directory + // + this.removeRequests(); + // + // Get our map + // + Map<Identifier, Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>>> attributeMap = this.aggregator.getAttributeMap(); + // + // We're going to create an initial flat list of requests for each unique attribute ID. Unique being the + // category, datatype and attribute id. + // + // By flattening the list, it makes it easier to then generate all the combinations of possible requests. + // + List<FlattenerObject> attributes = new ArrayList<FlattenerObject>(); + // + // Iterate through all the maps, we are going to flatten it + // out into an array list. + // + for (Map.Entry<Identifier, Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>>> categoryEntry : attributeMap.entrySet()) { + String category = categoryEntry.getKey().toString(); + if (logger.isDebugEnabled()) { + logger.debug("Category: " + category); + } + Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>> datatypeMap = categoryEntry.getValue(); + for (Map.Entry<Identifier, Map<Identifier, Set<AttributeValue<?>>>> datatypeEntry : datatypeMap.entrySet()) { + String datatype = datatypeEntry.getKey().toString(); + if (logger.isDebugEnabled()) { + logger.debug("\tData Type: " + datatype); + } + Map<Identifier, Set<AttributeValue<?>>> attributeIDMap = datatypeEntry.getValue(); + for (Map.Entry<Identifier, Set<AttributeValue<?>>> attributeIDEntry : attributeIDMap.entrySet()) { + String attributeID = attributeIDEntry.getKey().toString(); + if (logger.isDebugEnabled()) { + logger.debug("\t\tAttribute ID: " + attributeID); + } + Set<AttributeValue<?>> attributeValueSet = attributeIDEntry.getValue(); + // + // Sanity check to see if there are any values. Sometimes there isn't if an attribute + // is a designator that is part of a condition or variable. + // + if (attributeValueSet.isEmpty()) { + if (logger.isDebugEnabled()) { + logger.debug("No values for attribute " + attributeIDEntry.getKey().stringValue()); + } + // + // Check for the boolean datatype, in that case we can safely + // assume the true/false are ALL the possible values. + // + if (datatypeEntry.getKey().equals(XACML3.ID_DATATYPE_BOOLEAN) == false) { + // + // Not boolean, so skip it + // + continue; + } + if (logger.isDebugEnabled()) { + logger.debug("No values but its a boolean datatype, we will include it anyway."); + } + } + // + // Create our flattener object + // + FlattenerObject flat = new FlattenerObject(); + flat.category = categoryEntry.getKey(); + flat.datatype = datatypeEntry.getKey(); + flat.attribute = attributeIDEntry.getKey(); + flat.values = new HashSet<AttributeValue<?>>(); + if (datatypeEntry.getKey().equals(XACML3.ID_DATATYPE_BOOLEAN)) { + // + // There are only 2 possible values, true or false + // + flat.values.add(this.createAttributeValue(flat.datatype, true)); + flat.values.add(this.createAttributeValue(flat.datatype, false)); + } else { + flat.values.addAll(attributeValueSet); + } + attributes.add(flat); + } + } + } + if (attributes.size() <= 1) { + // + // Only one attribute, why bother + // + logger.info("Not enough attributes in policy: " + attributes.size()); + return; + } + /* + * PLD work more on this later. This combinatorial formula is only accurate if each + * attribute has one value. + * + */ + if (logger.isDebugEnabled()) { + // + // This isn't really accurate, if an attribute has more than one value + // + logger.debug(attributes.size() + " will generate " + computePossibleCombinations(attributes.size())); + } + this.index = 1; + for (int i = 0; i < attributes.size(); i++) { + FlattenerObject flat = attributes.get(i); + for (AttributeValue<?> value : flat.values) { + // + // Create a basic request object for just that attribute value. + // + RequestType request = new RequestType(); + // + AttributesType attrs = new AttributesType(); + attrs.setCategory(flat.category.stringValue()); + request.getAttributes().add(attrs); + // + AttributeType attr = new AttributeType(); + attr.setAttributeId(flat.attribute.stringValue()); + attrs.getAttribute().add(attr); + // + AttributeValueType val = new AttributeValueType(); + val.setDataType(flat.datatype.stringValue()); + if (value.getValue() instanceof Collection) { + val.getContent().addAll((Collection<? extends Object>) value.getValue()); + } else { + val.getContent().add(value.getValue().toString()); + } + // + attr.getAttributeValue().add(val); + // + // Dump it out + // + this.writeRequest(request); + // + // Initiate recursive call to add other attributes to the request + // + this.recursivelyGenerateRequests(request, i + 1, attributes); + } + } + } + + protected void recursivelyGenerateRequests(RequestType request, int i, List<FlattenerObject> attributes) { + if (logger.isTraceEnabled()) { + logger.trace("recursiveGenerate index: " + index + " i: " + i); + } + for ( ; i < attributes.size(); i++) { + FlattenerObject flat = attributes.get(i); + for (AttributeValue<?> value : flat.values) { + // + // Make a copy of the request + // + RequestType copyRequest = XACMLObjectCopy.deepCopy(request); + // + // Create the value object + // + AttributeValueType newValue = new AttributeValueType(); + newValue.setDataType(flat.datatype.stringValue()); + if (value.getValue() instanceof Collection) { + for (Object v : (Collection<?>) value.getValue()) { + newValue.getContent().add(v.toString()); + } + } else { + newValue.getContent().add(value.getValue().toString()); + } + // + // Add the value to the request + // + this.addAttribute(copyRequest, flat.category.stringValue(), flat.attribute.stringValue(), newValue); + // + // Now write it out + // + this.writeRequest(copyRequest); + // + // Recursively go through the rest of the attributes + // + this.recursivelyGenerateRequests(copyRequest, i + 1, attributes); + } + } + } + + public static long computePossibleCombinations(long numberOfAttributes) { + long num = 0; + for (long i = numberOfAttributes; i > 0; i--) { + num += computeCombinations(numberOfAttributes, i); + } + return num; + } + + public static long computeFactorial(long n) { + long fact = 1; + for (long i = 1; i <= n; i++) { + fact *= i; + } + return fact; + } + + public static long computePermutationsWithoutRepetition(long n, long r) { + // + // n! + // --------- + // (n - r)! + // + long nPrime = 1; + long n_rPrime = 1; + for (long i = n; i > 1; i--) { + nPrime *= i; + } + + for (long i = (n - r); i > 1; i--) { + n_rPrime *= i; + } + return nPrime / n_rPrime; + } + + public static long computeCombinations(long n, long r) { + // + // n! + // ----------- + // r! * (n-r)! + // + long nPrime = 1; + long rPrime = 1; + long n_rPrime = 1; + + for (long i = n; i > 1; i--) { + nPrime *= i; + } + + for (long i = r; i > 1; i--) { + rPrime *= i; + } + + for (long i = (n - r); i > 1; i--) { + n_rPrime *= i; + } + + return nPrime / (rPrime * n_rPrime); + } + + protected Set<AttributeValue<?>> getAttributeValues(RequestType request) { + // + // Get our map + // + Map<Identifier, Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>>> attributeMap = this.aggregator.getAttributeMap(); + // + // Find the attribute + // + AttributesType attrs = request.getAttributes().get(0); + Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>> categoryMap = attributeMap.get(new IdentifierImpl(attrs.getCategory())); + if (categoryMap != null) { + AttributeType a = attrs.getAttribute().get(0); + Map<Identifier, Set<AttributeValue<?>>> datatypeMap = categoryMap.get(new IdentifierImpl(a.getAttributeValue().get(0).getDataType())); + if (datatypeMap != null) { + Set<AttributeValue<?>> values = datatypeMap.get(new IdentifierImpl(a.getAttributeId())); + if (values != null) { + return values; + } + } + } + return Collections.emptySet(); + } + + protected AttributeValue<?> createAttributeValue(Identifier datatype, Object value) { + DataTypeFactory dataTypeFactory = null; + try { + dataTypeFactory = DataTypeFactory.newInstance(); + if (dataTypeFactory == null) { + logger.error("Could not create data type factory"); + return null; + } + } catch (FactoryException e) { + logger.error("Can't get Data type Factory: " + e.getLocalizedMessage()); + return null; + } + DataType<?> dataTypeExtended = dataTypeFactory.getDataType(datatype); + if (dataTypeExtended == null) { + logger.error("Unknown datatype: " + datatype); + return null; + } + try { + return dataTypeExtended.createAttributeValue(value); + } catch (DataTypeException e) { + logger.error(e); + } + return null; + } + + protected void removeRequests() { + // + // Delete any existing request files that we generate. i.e. Have the Unknown in the file name. + // + try { + Files.walkFileTree(Paths.get(this.directory.toString(), "requests"), new SimpleFileVisitor<Path>() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + // + // Sanity check the file name + // + Matcher matcher = pattern.matcher(file.getFileName().toString()); + if (matcher.matches()) { + try { + // + // Pull what this request is supposed to be + // + String group = null; + int count = matcher.groupCount(); + if (count >= 1) { + group = matcher.group(count-1); + } + // + // Send it + // + if (group.equals("Unknown")) { + // + // Remove the file + // + Files.delete(file); + } + } catch (Exception e) { + logger.error(e); + e.printStackTrace(); + } + } + return super.visitFile(file, attrs); + } + }); + } catch (IOException e) { + logger.error("Failed to removeRequests from " + this.directory + " " + e); + } + } + + protected void addRequests(RequestType request, List<RequestType> requests, int index) { + for (RequestType req : requests) { + // + // There really should only be one attribute + // + for (AttributesType attrs : req.getAttributes()) { + for (AttributeType attr : attrs.getAttribute()) { + for (AttributeValueType value : attr.getAttributeValue()) { + if (this.addAttribute(request, attrs.getCategory(), attr.getAttributeId(), value)) { + this.writeRequest(request); + } + } + } + } + } + } + + /** + * Writes the request into the "requests" sub-directory, relative to the value of the "directory" setup + * during initialization. + * + * Writing the requests out allows one to go back and easily refer to the request when analyzing the responses + * generated after the PDP decide() call. Also, one can then use the generated requests into any test tools + * they wish to build. + * + * @param request - The request to be written. + */ + protected void writeRequest(RequestType request) { + if (logger.isTraceEnabled()) { + logger.trace("writeRequest: " + index); + } + try { + ObjectFactory of = new ObjectFactory(); + JAXBElement<RequestType> requestElement = of.createRequest(request); + JAXBContext context = JAXBContext.newInstance(RequestType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + Path outFile = Paths.get(this.directory, "requests", String.format("Request.%06d.Unknown.xml", this.index)); + m.marshal(requestElement, outFile.toFile()); + } catch (Exception e) { + logger.error("Failed to write request: " + e.getMessage()); + } + this.index++; + } + + protected boolean addAttribute(RequestType request, String category, String id, AttributeValueType value) { + // + // See if the category exists + // + for (AttributesType attrs : request.getAttributes()) { + if (attrs.getCategory().equals(category)) { + // + // It does have the category. But does it have the attribute ID? + // + for (AttributeType attr : attrs.getAttribute()) { + if (attr.getAttributeId().equals(id)) { + // + // Yes, check for the same datatype + // + for (AttributeValueType val : attr.getAttributeValue()) { + if (val.getDataType().equals(value.getDataType())) { + // + // We have something already there + // + return false; + } + } + // + // The ID exists, but not the datatype + // + attr.getAttributeValue().add(value); + return true; + } + } + // + // If we get here, the ID does not exist + // + AttributeType attr = new AttributeType(); + attr.setAttributeId(id); + attr.getAttributeValue().add(value); + attrs.getAttribute().add(attr); + return true; + } + } + // + // If we get here, the category does not exist. So add it in. + // + AttributesType attrs = new AttributesType(); + attrs.setCategory(category); + AttributeType attr = new AttributeType(); + attr.setAttributeId(id); + attr.getAttributeValue().add(value); + attrs.getAttribute().add(attr); + request.getAttributes().add(attrs); + return true; + } + + public static void main(String[] args) { + try { + new TestPolicy(args).run(); + } catch (ParseException | IOException | FactoryException e) { + logger.error(e); + } catch (HelpException e) { + } + } + + /* + // Map<CATEGORY, MAP<DATATYPE, MAP<ATTRIBUTEID, SET<VALUES>>> + @SuppressWarnings("unchecked") + private void generateRequests(Map<Identifier, Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>>> categoryMap) { + meta = new ArrayList<>(); + + for (Map.Entry<Identifier, Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>>> categoryEntry : categoryMap.entrySet()) { + String category = categoryEntry.getKey().toString(); + logger.debug("Category: " + category); + Map<Identifier, Map<Identifier, Set<AttributeValue<?>>>> datatypeMap = categoryEntry.getValue(); + for (Map.Entry<Identifier, Map<Identifier, Set<AttributeValue<?>>>> datatypeEntry : datatypeMap.entrySet()) { + String datatype = datatypeEntry.getKey().toString(); + logger.debug("\tData Type: " + datatype); + Map<Identifier, Set<AttributeValue<?>>> attributeIDMap = datatypeEntry.getValue(); + for (Map.Entry<Identifier, Set<AttributeValue<?>>> attributeIDEntry : attributeIDMap.entrySet()) { + String attributeID = attributeIDEntry.getKey().toString(); + logger.debug("\t\tAttribute ID: " + attributeID); + Set<AttributeValue<?>> attributeValueSet = attributeIDEntry.getValue(); + for (AttributeValue<?> value : attributeValueSet) { + logger.debug("\t\t\tAttribute Value: " + value); + } + Iterator<AttributeValue<?>> iterator = attributeValueSet.iterator(); + logger.debug("\t\t\t# of Attribute values: " + attributeValueSet.size()); + meta.add(new Object[] {category, datatype, attributeID, iterator.next(), iterator, attributeValueSet}); + } + } + } + + int count = 0; + for (File file : output.toFile().listFiles()) { + file.delete(); + } + + do { + RequestType request = new RequestType(); + request.setCombinedDecision(false); + request.setReturnPolicyIdList(false); + List<AttributesType> attributesList = request.getAttributes(); + + Map<String, AttributesType> category2Attribute= new HashMap<>(); + for (int i = 0; i < meta.size(); i++) { + Object[] record = meta.get(i); + + AttributesType attributes = null; + if (category2Attribute.containsKey(record[0].toString())) + attributes = category2Attribute.get(record[0].toString()); + else { + attributes = new AttributesType(); + attributes.setCategory(record[0].toString()); + category2Attribute.put(record[0].toString(), attributes); + attributesList.add(attributes); + } +// attributes.setId(record[2].toString()); + List<AttributeType> attrList = attributes.getAttribute(); + + AttributeType attribute = new AttributeType(); + attribute.setAttributeId(record[2].toString()); + List<AttributeValueType> valueList = attribute.getAttributeValue(); + + AttributeValue<?> attributeValue = (AttributeValue<?>) record[3]; + + AttributeValueType value = new AttributeValueType(); + value.setDataType(attributeValue.getDataTypeId().toString()); + List<Object> content = value.getContent(); + content.addAll((Collection<? extends Object>) attributeValue.getValue()); + valueList.add(value); + + attrList.add(attribute); + } + + try { + ObjectFactory of = new ObjectFactory(); + JAXBElement<RequestType> requestElement = of.createRequest(request); + JAXBContext context = JAXBContext.newInstance(RequestType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(requestElement, output.resolve("request" + count + ".xml").toFile()); + +// if (count == 0) {//Just send the first request to the engine + StringWriter sw = new StringWriter(); + m.marshal(requestElement, sw); + logger.info(sw.toString()); + EngineCaller engine = new LocalEngineCaller(); + if (engine.startEngine("")) { + String response = engine.decide(sw.toString(), "xml"); + FileWriter writer = new FileWriter(output.resolve("response" + count + ".xml").toFile()); + writer.write(response); + writer.close(); + logger.info("Response received: \n" + response); + } +// } + } catch (Exception e) { + e.printStackTrace(); + } + + count++; + } while (hasNextRequest()); + + logger.info("# of requests generated: " + count); + } + + private boolean hasNextRequest() { + int i = meta.size() - 1; + Object[] record = meta.get(i); + + @SuppressWarnings("unchecked") + Iterator<AttributeValue<?>> iterator = (Iterator<AttributeValue<?>>) record[4]; + if (iterator.hasNext()) { + record[3] = iterator.next(); + } else { + return recycleAttributeValue(i); + } + + return true; + } + + @SuppressWarnings("unchecked") + private boolean recycleAttributeValue(int position) { + boolean rc = true; + + if (position == 0) + return false; + + Object[] record = meta.get(position); + Set<AttributeValue<?>> attributeValueSet = (Set<AttributeValue<?>>) record[5]; + Iterator<AttributeValue<?>> newIt = attributeValueSet.iterator(); + record[4] = newIt; + record[3] = newIt.next(); + int i = position - 1; + Object[] previous = meta.get(i); + Iterator<AttributeValue<?>> preIt = (Iterator<AttributeValue<?>>) previous[4]; + if (preIt.hasNext()) { + previous[3] = preIt.next(); + } else { + rc = recycleAttributeValue(i); + } + + return rc; + } + + */ + +} + diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/XACMLEngineTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/XACMLEngineTest.java new file mode 100644 index 000000000..660180b9b --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/XACMLEngineTest.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import junit.framework.TestCase; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletConfig; + +public class XACMLEngineTest extends TestCase{ + + private List<String> headers = new ArrayList<String>(); + + private HttpServletRequest httpServletRequest; + private HttpServletResponse httpServletResponse; + private ServletOutputStream mockOutput; + private ServletConfig servletConfig; + + @Before + + public void setUp() throws IOException { + httpServletRequest = Mockito.mock(HttpServletRequest.class); + Mockito.when(httpServletRequest.getMethod()).thenReturn("POST"); + Mockito.when(httpServletRequest.getParameter("groupId")).thenReturn(null); + Mockito.when(httpServletRequest.getHeaderNames()).thenReturn(Collections.enumeration(headers)); + Mockito.when(httpServletRequest.getAttributeNames()).thenReturn(Collections.enumeration(headers)); + + + mockOutput = Mockito.mock(ServletOutputStream.class); + + httpServletResponse = Mockito.mock(MockHttpServletResponse.class); + + Mockito.when(httpServletResponse.getOutputStream()).thenReturn(mockOutput); + + servletConfig = Mockito.mock(MockServletConfig.class); + + Mockito.when(servletConfig.getInitParameterNames()).thenReturn(Collections.enumeration(headers)); + + + + } + + @Test + public void testDummy() throws Exception{ + try { + assertTrue(true); + } catch (Exception e) { + fail(); + } + + } + +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/components/XACMLPDPPolicyTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/components/XACMLPDPPolicyTest.java new file mode 100644 index 000000000..96163b20e --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/components/XACMLPDPPolicyTest.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.components; + +import org.junit.Test; +import org.junit.Before; +import org.junit.After; + +import org.junit.Assert; + +public class XACMLPDPPolicyTest { + + + @Before + public void init(){ + + } + + @After + public void cleanUp(){ + + } + + @Test + public void testDummy(){ + + Assert.assertTrue(true); + + } + +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestCategoryTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestCategoryTest.java new file mode 100644 index 000000000..e4ef4bef7 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestCategoryTest.java @@ -0,0 +1,4174 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; + +/** + * Test JSON Request convert to object - Category sub-component. Does not include "Default" Categories (Subject, Action, Resource, Environment). + * Basic existance/absence of Category is tested in RequestMainTest. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * + */ +public class RequestCategoryTest { + + // The request object output from each test conversion from JSON string + Request request; + + + /* + * Request that uses all fields with both single and multiple entries + */ + String allFieldsRequest = + "{\"Request\": {" + + "\"ReturnPolicyIdList\" : true ," + + "\"CombinedDecision\" : true ," + + "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar1\"]" + + "}]" + + "}," + + + "\"Category\": [" + + "{ " + + "\"CategoryId\": \"custom-category\", " + + "\"Id\" : \"customId\", " + + "\"Attribute\" : [" + + "{" + + "\"AttributeId\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}, " + + "{" + + "\"AttributeId\" : \"document-url\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " + + "}, " + + "{" + + "\"AttributeId\" : \"page-list\", " + + "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " + + "} " + + "]" + + "}, " + + "{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "], " + + + "\"AccessSubject\":{ " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"," + + "\"Attribute\" : []" + + "}, " + + + "\"Resource\" : {" + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + + + "} " + + + + "}}"; + + /* + * The following example comes directly from the JSON Profile Spec + */ + String exampleFromSpec = "{ " + + "\"Request\" : { " + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "\"Action\" : { " + + "\"Attribute\": " + + "{ " + + "\"Id\" : \"action-id\", " + + "\"Value\" : \"http://www.xacml.eu/buy\", " + + "\"DataType\" : \"anyURI\" " + + "} " + + "}, " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"book-title\", " + + "\"Value\" : \"Learn German in 90 days\" " + + "}, " + + "{ " + + "\"Id\" : \"currency\", " + + "\"Value\" : \"SEK\" " + + "}, " + + "{ " + + "\"Id\" : \"price\", " + + "\"Value\" : 123.34 " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + /* + * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples). + * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding. + */ + String xPathExampleFromSpec = "{ " + + "\"Request\" : { " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : { " + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " + + "\"Namespaces\" : [{ " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}, " + + "{ " + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "} " + + "], " + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " + + "} " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Top-level of Category + @Test + public void testCategoryTopLevel() { + + // empty Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Missing value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\" }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\" : }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category without CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{}] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with CategoryId value missing or ="" + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\"] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"\" ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // CategoryId wrong type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : true } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : \"customId\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category},xmlId=customId}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Id - wrong type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : true } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Id\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category without Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category with standard CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with extra unknown field + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", unknown } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"unknown\" : 123 } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with multiple sub-Category objects using same CategoryId + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"category1\" }, {\"CategoryId\" : \"category1\" } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=category1}}{super={category=category1}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + // Tests related to Attributes + @Test + public void testCategoryAttributes() { + + // Category with Attribute but none given ("Attribute" : [] ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with empty attribute (missing both AttributeId and Id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with AttributeId and no Value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing AttributeId but with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing AttributeId but with Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute including both AttributeId and Id with same value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : \"document-id\", " + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute missing both AttributeId and Id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute AttributeId not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"AttributeId\" : 123, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute Id not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : 123, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with DataType not string (e.g. "DataType" : 55.5 ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : true, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with unknown DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"no such data type\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : 321, " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with multiple value array + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [\"P3D\", \"P2DT12H34M\", \"PT15M\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=2hours=12minutes=34seconds=0millis=0},factionalSeconds=0.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=0hours=0minutes=15seconds=0millis=0},factionalSeconds=0.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute multiple value with null in array + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [\"P3D\", , \"P15M\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with array value with no values ("Attribute": [ {"AttributeId" :"a", Value:[] } ] } ) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [ ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with no DataType and array with no values + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Issuer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : \"University Press\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],issuer=University Press,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Issuer not string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : true, " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Issuer\" : 4.56, " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult=true + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=true}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult = false + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : false " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with includeInResult not boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : \"abc\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123, " + + "\"IncludeInResult\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + // Tests related to DataTypes within Attributes + @Test + public void testCategoryAttributesDataTypesSimple() { + + // Category Attribute using full Identifier for each data type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : \"10.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute shorthand notation for each data type + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"string\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"boolean\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"double\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"time\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"date\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dateTime\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"yearMonthDuration\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"hexBinary\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"base64Binary\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,2,35,-13,-29,-58,54,23,70,22,-58,-10,115,-29,-58,38,-10,-10,-78,6,-106,67,-46,38,38,-77,19,3,18,35,-29,-58,23,87,70,-122,-9]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"rfc822Name\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.COMPANY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"ipAddress\", " + + "\"Value\" : \"10.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dnsName\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // infer data type - only integer, boolean and double are distinguishable from strings; everything else is treated as a string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"2002-10-10\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"2002-10-10T12:00:00Z\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"P23DT7H12M54S\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"P165Y8M\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"FA027B7D12CC34DDD20012AEEF\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"someone.else@A.COMPANY.com\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.COMPANY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"cn=Julius Hibbert, o=Medi Corporation, c=US\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"10.221.43.58:12345\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + // gets inferred to a String containing the whole structure under Value as a String + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value={XPathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource, Namespaces=[{Namespace=urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}, {Prefix=md, Namespace=urn:example:med:schemas:record}], XPath=md:record/md:patient/md:patientDoB}}],includeInResults=false}]}}]}", request.toString()); + + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + @Test + public void testCategoryAttributesDataTypesNotMatchValue() { + + // Category Attribute with DataType not matching value type (JSON type derived from syntax) + // AUTO-CONVERSION from Boolean to String! + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : true " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : 123.34 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : \"abc\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"123\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : true " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 123.45 " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : \"123.34\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : true " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // allow integer to auto-convert to double when DataType is given + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : 123 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // special JavaScript values not allowed except for -0 (inappropriate requirement in spec - check it anyway) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"NaN\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"INF\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : \"-INF\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // JavaScript 0 and -0 are ok + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : 0 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : -0 " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // All other data types are checked when we convert internally, so value must be syntactically correct + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Base64 convert does not throw an exception if the contents are not Base64, so cannot test for this. + // Any problem with the data will have to be discovered later when the data is used. + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : \"syntactically incorrect value\" " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Cannot test XPathExpressions here. The XPathExpression gets converted into a simple String value within the XPathExpression object, + // but it is not evaluated or compiled at that time. Therefore we do not know whether or not the value is valid until it is used in a computation. + + } + + + @Test + public void testArrayDataTypes() { + + // array of size 0 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute value array DataType given (repeat for all data types) + // Category Attribute using full Identifier for each data type + // Category Attribute shorthand notation for each data type + // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible) + // string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"string\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT to DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"boolean\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, \"abc\", false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, 123, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#boolean\", " + + "\"Value\" : [true, 12.34, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // integer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, \"abc\", 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, true, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#integer\", " + + "\"Value\" : [123, 34.56, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // double + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"double\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // special case - auto-convert integer to boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#double\", " + + "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // time + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"time\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#time,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", \"not a time\", \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#time\", " + + "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // date + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"date\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#date,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",\"not a date\",\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#date\", " + + "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dateTime + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#dateTime,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"not a dateTime\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dateTime\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dayTimeDuration + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}{dataTypeId=http://www.w3.org/2001/XMLSchema#dayTimeDuration,value={super={durationSign=1years=0months=0days=23hours=7minutes=12seconds=54millis=0},factionalSeconds=54.0}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"not a duration\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#dayTimeDuration\", " + + "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // yearMonth duration + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}{dataTypeId=http://www.w3.org/2001/XMLSchema#yearMonthDuration,value={super={durationSign=1years=165months=8days=0hours=0minutes=0seconds=0millis=0},monthsDuration=1988}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",\"not a duration\",\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#yearMonthDuration\", " + + "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // anyURI + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",true,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",123,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#anyURI\", " + + "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // hexBinary + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#hexBinary,value={data=[-6,2,123,125,18,-52,52,-35,-46,0,18,-82,-17]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#hexBinary\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // base64Binary + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"base64Binary\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,-46,35,18,-29,18,35,-29,-58,23,87,70,-122,-9]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-74,-69,-98]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-73]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#base64Binary\", " + + "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[104,111,114]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-41,93,-74]}}{dataTypeId=http://www.w3.org/2001/XMLSchema#base64Binary,value={data=[-106,-10,-29,34,62,60,97,117,116,104,111,114]}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // RFC822 name + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=sne.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=one.else,domainName=A.COMPANY.com}}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name,value={localName=someone.else,domainName=A.CONY.com}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"not a dns\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // x500 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}{dataTypeId=urn:oasis:names:tc:xacml:1.0:data-type:x500Name,value=CN=Julius Hibbert, O=Medi Corporation, C=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"non-x500 string\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:1.0:data-type:x500Name\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // ipAddress + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",\"10.221.43.58:12345\",\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",\"10.221.43.58:12345\",\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:ipAddress,value=10.221.43.58:12345-12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",\"not an ip address\",\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",true,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",1111,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress\", " + + "\"Value\" : [ \"10.221.43.58:12345\",11.22,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dnsName + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"dnsName\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=true}}{dataTypeId=urn:oasis:names:tc:xacml:2.0:data-type:dnsName,value={domainName=aValue}}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:2.0:data-type:dnsName\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // xPathExpression + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "\"simpleString\"," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "true," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "123," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\", " + + "\"Value\" : [ " + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}," + + "12.34," + + "{" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + } + + + + + + + + @Test + public void testArrayNoDataTypes() { + + // array of size 0 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute value array DataType Not given (repeat for all data types) + // Also tests for mixes of different JSON types (trying incorrect strings for XACML data types whenever possible) + // string + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", \"def\", \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=def}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT to DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", true, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\",123, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"abc\", 34.34, \"hig\", \"lmn\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=34.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=hig}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lmn}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, true, false, true, false ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#boolean,value=false}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, \"abc\", false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, 123, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [true, 12.34, false, true, false ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // integer + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, 456, 765, 234] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=456}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=765}{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=234}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, \"abc\", 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [123, true, 765, 234] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // double + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, 543.54, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.54}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // special case - auto-convert integer to boolean + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, 111122, 3445.455, 4543,543 ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=111122.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3445.455}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4543.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=543.0}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, true, 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ 123.34, \"abb\", 3445.455, 4543,543 ] " + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // time - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", \"12:00:00Z\", \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", true, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // SUCCESSFUL AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", 123, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"12:00:00Z\", 12.34, \"12:00:00Z\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // date - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",\"2002-10-10\",\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",true,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",123,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [\"2002-10-10\",123.45,\"2002-10-10\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123.45}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dateTime - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\",\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",true,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",123,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"2002-10-10T12:00:00Z\",12.34,\"2002-10-10T12:00:00Z\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=12.34}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=2002-10-10T12:00:00Z}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dayTimeDuration - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",\"P23DT7H12M54S\",\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + //AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",true,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",123,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P23DT7H12M54S\",11.22,\"P23DT7H12M54S\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P23DT7H12M54S}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // yearMonth duration - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",\"P165Y8M\",\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",true,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",123,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"P165Y8M\",11.22,\"P165Y8M\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=P165Y8M}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // anyURI - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",true,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",123,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",11.111,\"aValue\"] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // hexBinary - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\",\"FA027B7D12CC34DDD20012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",true,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",123,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"FA027B7D12CC34DDD20012AEEF\",11.44,\"012AEEF\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=FA027B7D12CC34DDD20012AEEF}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.44}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=012AEEF}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // base64Binary - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",\"lvbj0iMS4xIj48YXV0aG9y\",\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbj0iMS4xIj48YXV0aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",true,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",1123,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1123}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aG9y\",11.22,\"lvbjIj48YXV0aG9y\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aG9y}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=lvbjIj48YXV0aG9y}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // RFC822 name - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",\"one.else@A.COMPANY.com\",\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=one.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",true,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",111,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"sne.else@A.COMPANY.com\",11.22,\"someone.else@A.CONY.com\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=sne.else@A.COMPANY.com}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=someone.else@A.CONY.com}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // x500 - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\", \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", true, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 1111, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"cn=Julius Hibbert, o=Medi Corporation, c=US\", 11.22, \"cn=Julius Hibbert, o=Medi Corporation, c=US\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=cn=Julius Hibbert, o=Medi Corporation, c=US}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // ipAddress - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"10.221.43.58:12345\",\"10.221.43.58:12345\",\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"10.221.43.58:12345\",true,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"10.221.43.58:12345\",1111,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"10.221.43.58:12345\",11.22,\"10.221.43.58:12345\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=10.221.43.58:12345}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // dnsName - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // xPathExpression - defaults to String + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", true, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=true}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 1111, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=1111}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + // AUTO-CONVERT + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", 11.22, \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=11.22}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + @Test + public void testXPathExpression() { + // Category Attribute with XPathExpression including XPathCategory and XPath + // Category Attribute with XPathExpression with Namespaces with/without Prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [" + + "{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{ "+ + "\"Prefix\" : \"lab\", " + + "\"Namespace\" : \"http://somewhere/uri.html\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{lab,http://somewhere/uri.html}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression missing XPathCategory + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression missing XPath + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}] "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression without Namespaces + // (path does not contain namespace references) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"XPath\" : \"record/patient/patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=record/patient/patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression with 0 Namespaces + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with XPathExpression with Namespaces without mandatory Namespace + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression with Namespaces with 2 namespaces using same prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [{ "+ + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression without Namespaces which are used within the XPathExpression (NOTE: Error is not syntactic and is not found by converter) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace=null,status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with XPathExpression containing simple value (must be object) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : \"simple Value\"" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces containing simple value (must be object) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ \"simpleValue\"," + + "{" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category Attribute with Namespaces non-string Namespace + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : 123 " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string prefix + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : 123, " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string XPathCategory + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : 123," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category Attribute with Namespaces non-string XPath + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : {" + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\"," + + "\"Namespaces\" : [ {" + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "}], "+ + "\"XPath\" : 123 "+ + "}" + + "}] } ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + @Test + public void testContent() { + + // Category with Content in XML, escaped properly + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Content in XML, double quotes and back-slashes NOT escaped properly? + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Content in Base64 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + "} ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]},contentRoot=[catalog: null]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Category with Bad Content in Base64 + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"PD94bWwgdmV\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + + @Test + public void testDuplicates() { + // duplicate of same element within Category array is ok + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] }, " + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=abc}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // duplicate Attribute + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"custom-category\"," + + " \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}], " + + " \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup id + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup DataType + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // dup Value + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"DataType\" : \"http://www.w3.org/2001/XMLSchema#string\", " + + "\"Value\" : \"abc\" " + + "\"Value\" : \"abc\" " + + "}] } " + + "] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // duplicate Content + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{" + + "\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\",\"aValue\",\"aValue\"] " + + "}]," + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\" , " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"" + + "} ] }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + +//TODO - Shorthand for CategoryId ???? + + +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestConformanceTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestConformanceTest.java new file mode 100644 index 000000000..6c30cb481 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestConformanceTest.java @@ -0,0 +1,253 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.RequestAttributes; +import com.att.research.xacml.api.RequestReference; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; +/** + * Test JSON Request convert to object - Conformance tests + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * + */ +public class RequestConformanceTest { + + // where to find the conformance test XML files + private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4"; + + // The request object output from each test conversion from JSON string + Request request; + + + + + + // test just one of each top-level element. + // For simple elements also test for incorrect type + @Test + public void testConformanceRequests() { + + List<File> filesInDirectory = null; + + File conformanceDirectory = null; + + File currentFile = null; + + try { + conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH); + filesInDirectory = getRequestsInDirectory(conformanceDirectory); + } catch (Exception e) { + fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e); + } + + // run through each XML file + // - load the file from XML into an internal Request object + // - generate the JSON representation of that Request object + // - load that JSON representation into a new Request object + // - compare the 2 Request objects + Request xmlRequest = null; + Request jsonRequest = null; + try { + for (File f : filesInDirectory) { + currentFile = f; + +//// This is a simple way to select just one file for debugging - comment out when not being used +//if ( ! f.getName().equals("IIA023Request.xml")) { continue; } + +// during debugging it is helpful to know what file it is starting to work on +// System.out.println("starting file="+currentFile.getName()); + + try { + // load XML into a Request object + xmlRequest = DOMRequest.load(f); + xmlRequest.getStatus(); + } catch (Exception e) { + // if XML does not load, just note it and continue with next file + System.out.println("XML file did not load: '" + f.getName() + " e=" + e); + continue; + } + +//System.out.println(JSONRequest.toString(xmlRequest, false)); + + // generate JSON from the Request + String jsonString = JSONRequest.toString(xmlRequest, false); + + // load JSON into a Request + jsonRequest = JSONRequest.load(jsonString); + + // compare the two Request objects + + // check simple things first + assertEquals("File '" + currentFile.getName() + "' CombinedDecision", xmlRequest.getCombinedDecision(), jsonRequest.getCombinedDecision()); + assertEquals("File '" + currentFile.getName() + "' getReturnPolicyIdList", xmlRequest.getReturnPolicyIdList(), jsonRequest.getReturnPolicyIdList()); + assertEquals("File '" + currentFile.getName() + "' requestDefaults", xmlRequest.getRequestDefaults(), jsonRequest.getRequestDefaults()); + + // multiRequests (guaranteed to not be null) + // We do NOT care about ordering, so compare the two collections inefficiently + Collection<RequestReference> xmlCollection = xmlRequest.getMultiRequests(); + Collection<RequestReference> jsonCollection = jsonRequest.getMultiRequests(); + String errorMessage = null; + if (jsonCollection.size() != xmlCollection.size()) { + errorMessage = "File '" + currentFile.getName() + "' MultiRequests not same size. "; + } else if (! jsonCollection.containsAll(xmlCollection)) { + errorMessage = "File '" + currentFile.getName() + "' MultiRequests have different contents. "; + } + if (errorMessage != null) { + String xmlContents = ""; + String jsonContents = ""; + Iterator<RequestReference> rrIt = xmlCollection.iterator(); + while (rrIt.hasNext()) { + xmlContents += "\n " + rrIt.next().toString(); + } + rrIt = jsonCollection.iterator(); + while (rrIt.hasNext()) { + jsonContents += "\n " + rrIt.next().toString(); + } + fail(errorMessage + "\nXML(" + xmlCollection.size() + ")='" + xmlContents + + "' \nJSON(" + jsonCollection.size() + ")='" + jsonContents + + "'" + + "\njson='" + jsonString + "'"); + } + + // attributes (guaranteed to not be null) + // We do NOT care about ordering, so compare the two collections inefficiently + Collection<RequestAttributes> xmlAttrCollection = xmlRequest.getRequestAttributes(); + Collection<RequestAttributes> jsonAttrCollection = jsonRequest.getRequestAttributes(); + errorMessage = null; + if (jsonAttrCollection.size() != xmlAttrCollection.size()) { + errorMessage = "File '" + currentFile.getName() + "' RequestAttributes not same size. "; + } else if (! jsonAttrCollection.containsAll(xmlAttrCollection)) { + String attrName = ""; + Iterator<RequestAttributes> rait = xmlAttrCollection.iterator(); + while (rait.hasNext()) { + RequestAttributes ra = rait.next(); + if (jsonAttrCollection.contains(ra) == false) { + attrName = ra.toString(); + } + } + errorMessage = "File '" + currentFile.getName() + "' RequestAttributes have different contents. JSON is missing attr=" + attrName; + } + if (errorMessage != null) { + String xmlContents = ""; + String jsonContents = ""; + Iterator<RequestAttributes> rrIt = xmlAttrCollection.iterator(); + while (rrIt.hasNext()) { + RequestAttributes ras = rrIt.next(); + xmlContents += "\n " + ras.toString(); + if (ras.getContentRoot() != null) { + StringWriter writer = new StringWriter(); + Transformer transformer = null; + try { + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer)); + } catch (Exception e) { + throw new JSONStructureException("Unable to Content node to string; e="+e); + } + + xmlContents += "\n Content: " + writer.toString(); + } + } + rrIt = jsonAttrCollection.iterator(); + while (rrIt.hasNext()) { + RequestAttributes ras = rrIt.next(); + jsonContents += "\n " + ras.toString(); + if (ras.getContentRoot() != null) { + StringWriter writer = new StringWriter(); + Transformer transformer = null; + try { + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(ras.getContentRoot()), new StreamResult(writer)); + } catch (Exception e) { + throw new JSONStructureException("Unable to Content node to string; e="+e); + } + + jsonContents += "\n Content: " + writer.toString(); + } + } + fail(errorMessage + "\nXML(" + xmlAttrCollection.size() + ")='" + xmlContents + + "' \nJSON(" + jsonAttrCollection.size() + ")='" + jsonContents + + "\njson='" + jsonString + "'"); + } + + + } + + } catch (Exception e) { + fail ("Failed test with '" + currentFile.getName() + "', e=" + e); + } + + + } + + // + // HELPER to get list of all Request files in the given directory + // + + private List<File> getRequestsInDirectory(File directory) { + List<File> fileList = new ArrayList<File>(); + + File[] fileArray = directory.listFiles(); + for (File f : fileArray) { + if (f.isDirectory()) { + List<File> subDirList = getRequestsInDirectory(f); + fileList.addAll(subDirList); + } + if (f.getName().endsWith("Request.xml")) { + fileList.add(f); + } + } + return fileList; + + } + +}
\ No newline at end of file diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestDefaultCategoryTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestDefaultCategoryTest.java new file mode 100644 index 000000000..a5929a4d8 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestDefaultCategoryTest.java @@ -0,0 +1,1427 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; +/** + * Test JSON Request convert to object - Default Category object tests + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * + */ +public class RequestDefaultCategoryTest { + + // The request object output from each test conversion from JSON string + Request request; + + + /* + * Request that uses all fields with both single and multiple entries + */ + String allFieldsRequest = + "{\"Request\": {" + + "\"ReturnPolicyIdList\" : true ," + + "\"CombinedDecision\" : true ," + + "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar1\"]" + + "}]" + + "}," + + + "\"Category\": [" + + "{ " + + "\"CategoryId\": \"custom-category\", " + + "\"Id\" : \"customId\", " + + "\"Attribute\" : [" + + "{" + + "\"AttributeId\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}, " + + "{" + + "\"AttributeId\" : \"document-url\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " + + "}, " + + "{" + + "\"AttributeId\" : \"page-list\", " + + "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " + + "} " + + "]" + + "}, " + + "{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "], " + + + "\"AccessSubject\":{ " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"," + + "\"Attribute\" : []" + + "}, " + + + "\"Resource\" : {" + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + + + "} " + + + + "}}"; + + /* + * The following example comes directly from the JSON Profile Spec + */ + String exampleFromSpec = "{ " + + "\"Request\" : { " + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "\"Action\" : { " + + "\"Attribute\": " + + "{ " + + "\"Id\" : \"action-id\", " + + "\"Value\" : \"http://www.xacml.eu/buy\", " + + "\"DataType\" : \"anyURI\" " + + "} " + + "}, " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"book-title\", " + + "\"Value\" : \"Learn German in 90 days\" " + + "}, " + + "{ " + + "\"Id\" : \"currency\", " + + "\"Value\" : \"SEK\" " + + "}, " + + "{ " + + "\"Id\" : \"price\", " + + "\"Value\" : 123.34 " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + /* + * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples). + * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding. + */ + String xPathExampleFromSpec = "{ " + + "\"Request\" : { " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : { " + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " + + "\"Namespaces\" : [{ " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}, " + + "{ " + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "} " + + "], " + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " + + "} " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + // test Shorthand Category notation for elements not tested in their own section below. + // Categories that are more commonly used are fully tested. + // Given that the functions within the categories are the same irrespective of the name of the category, + // we assume that the contents of the category will work ok once the Shorthand notation is recognized, so all we need to test is the shorthand + // The ones that are tested in their own sections are: + // AccessSubject + // Action + // Resource + // Environment + // test Subject + @Test + public void testCategoryShorthand() { + + // RecipientSubject present both as element within Category and as separate RecipientSubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"RecipientSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // IntermediarySubject present both as element within Category and as separate IntermediarySubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"IntermediarySubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Codebase present both as element within Category and as separate Codebase element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:codebase\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Codebase\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:codebase,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // RequestingMachine present both as element within Category and as separate RequestingMachine element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"RequestingMachine\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + + + + + + + + + + + + + + // test AccessSubject + // Include test for backward compatibility with "Subject" + @Test + public void testAccessSubjectRequest() { + + // AccessSubject absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple AccessSubjects under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present both as element within Category and as separate AccessSubject element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Subject present, no other Category element (Backward Compatibility + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Subject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 AccessSubjects - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject with array of sub-object AccessSubjects (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"AccessSubject\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + + + + + + // Action ... duplicate all AccessSubject tests... + // test Action + @Test + public void testActionRequest() { + + // Action absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple Actions under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present both as element within Category and as separate Action element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 Actions - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"Action\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action with array of sub-object Actions (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Action\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + // Resource ... duplicate all AccessSubject tests... + // test Resource + @Test + public void testResourceRequest() { + + // Resource absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple Resources under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource present both as element within Category and as separate Resource element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 Resources - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Resource\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Resource\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource with array of sub-object Resources (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Resource\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + + + // Environment ... duplicate all AccessSubject tests ... + // test Environment + @Test + public void testEnvironmentRequest() { + + // Environment absent + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment as normal element under Category (with CategoryId==subject category id) + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\" " + + "}] } ] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // multiple Environments under Category + try { + request = JSONRequest.load("{\"Request\" : {\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment present both as element within Category and as separate Environment element at same level as Category + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : [ \"aValue\", \"aValue\", \"aValue\" ] " + + "}] }, " + + "{\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Environment\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=document-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment present, no other Category element + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Environment\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment present, 1/multiple other Category element also present + try { + request = JSONRequest.load("{\"Request\" : {" + + "\"Category\": [" + + "{\"CategoryId\" : \"custom-category\", \"Attribute\" : [{" + + "\"Id\" : \"document-id\", " + + "\"Value\" : \"aValue\"" + + "}] } " + + "]," + + "\"Environment\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=aValue}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // 2 Environments - duplicates fail + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Environment\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + + "\"Environment\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment with correct Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Environment\" : { " + + "\"CategoryId\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment with wrong Category value + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Environment\" : { " + + "\"CategoryId\" : \"notthesubject\" ," + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "} " + + " }}"); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment with array of sub-object Environments (Multi Decision) + try { + request = JSONRequest.load("{\"Request\" : {" + + + "\"Environment\" : [" + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Arless\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Somewhere\" " + + "} " + + "] " + + "}, " + + "{ " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Barry\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Elsewhere\" " + + "} " + + "] " + + "} " + + "]" + + " }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Arless}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Somewhere}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Barry}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Elsewhere}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestMainTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestMainTest.java new file mode 100644 index 000000000..198ba3ae6 --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/RequestMainTest.java @@ -0,0 +1,1076 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.std.json.JSONRequest; +import com.att.research.xacml.std.json.JSONStructureException; +/** + * Test JSON Request convert to object - High-level Request-as-a-whole tests including test that fills in all fields with multiple values (where appropriate) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOTE: + * The "correct" way to verify that each JSON string gets translated into our internal Objects correctly is to look explicitly at each of the child objects + * and verify that they are correct. This would involve a lot of coding to get child of child of child and individually verify each property of each element. + * To simplify testing we assume that request.toString() correctly includes a complete text representation of every sub-component of the Request object + * and we compare the resulting String to our expected String. + * This has two possible sources of error: + * - toString might not include some sub-component, and + * - the initial verification of the resulting string is done by hand and may have been incorrect. + * + * + */ +public class RequestMainTest { + + // The request object output from each test conversion from JSON string + Request request; + + + /* + * Request that uses all fields with both single and multiple entries + */ + String allFieldsRequest = + "{\"Request\": {" + + "\"ReturnPolicyIdList\" : true ," + + "\"CombinedDecision\" : true ," + + "\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar1\"]" + + "}]" + + "}," + + + "\"Category\": [" + + "{ " + + "\"CategoryId\": \"custom-category\", " + + "\"Id\" : \"customId\", " + + "\"Attribute\" : [" + + "{" + + "\"AttributeId\" : \"document-id\", " + + "\"DataType\" : \"integer\", " + + "\"Value\" : 123 " + + "}, " + + "{" + + "\"AttributeId\" : \"document-url\", " + + "\"DataType\" : \"anyURI\", " + + "\"Value\" : \"http://somewhere.over.the.com/rainbow\" " + + "}, " + + "{" + + "\"AttributeId\" : \"page-list\", " + + "\"Value\" : [1, 2, 3, 4.5, 3, 2, 1] " + + "} " + + "]" + + "}, " + + "{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "], " + + + "\"AccessSubject\":{ " + + "\"Content\" : \"<?xml version=\\\"1.0\\\"?><catalog>" + + "<book id=\\\"bk101\\\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre>" + + "<price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description>"+ + "</book></catalog>\"," + + "\"Attribute\" : []" + + "}, " + + + "\"Resource\" : {" + + "\"Content\" : \"PD94bWwgdmVyc2lvbj0iMS4wIj8+PGNhdGFsb2c+PGJvb2sgaWQ9ImJrMTAxIj48YXV0aG9yPkdhbWJhcmRlbGxhLCBNYXR0aGV3PC9hdXRob3I+PHRpdGxlPlhNT" + + "CBEZXZlbG9wZXIncyBHdWlkZTwvdGl0bGU+PGdlbnJlPkNvbXB1dGVyPC9nZW5yZT48cHJpY2U+NDQuOTU8L3ByaWNlPjxwdWJsaXNoX2RhdGU+MjAwMC0xMC0wMTwvcHVibGlzaF"+ + "9kYXRlPjxkZXNjcmlwdGlvbj5BbiBpbi1kZXB0aCBsb29rIGF0IGNyZWF0aW5nIGFwcGxpY2F0aW9ucyB3aXRoIFhNTC48L2Rlc2NyaXB0aW9uPjwvYm9vaz48L2NhdGFsb2c+\"" + + + + "} " + + + + "}}"; + + /* + * The following example comes directly from the JSON Profile Spec + */ + String exampleFromSpec = "{ " + + "\"Request\" : { " + + "\"AccessSubject\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"subject-id\", " + + "\"Value\" : \"Andreas\" " + + "}, " + + "{ " + + "\"Id\" : \"location\", " + + "\"Value\" : \"Gamla Stan\" " + + "} " + + "] " + + "}, " + + "\"Action\" : { " + + "\"Attribute\": " + + "{ " + + "\"Id\" : \"action-id\", " + + "\"Value\" : \"http://www.xacml.eu/buy\", " + + "\"DataType\" : \"anyURI\" " + + "} " + + "}, " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"book-title\", " + + "\"Value\" : \"Learn German in 90 days\" " + + "}, " + + "{ " + + "\"Id\" : \"currency\", " + + "\"Value\" : \"SEK\" " + + "}, " + + "{ " + + "\"Id\" : \"price\", " + + "\"Value\" : 123.34 " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + /* + * The following example comes directly from the JSON Profile Spec (modified to include a "</Catalog>" missing from both examples). + * It shows the two ways of handling XPath content, as escaped XML and as Base64 encoding. + */ + String xPathExampleFromSpec = "{ " + + "\"Request\" : { " + + "\"Resource\" : { " + + "\"Attribute\": [ " + + "{ " + + "\"Id\" : \"urn:oasis:names:tc:xacml:3.0:content-selector\", " + + "\"DataType\" : \"xpathExpression\", " + + "\"Value\" : { " + + "\"XPathCategory\" : \"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\", " + + "\"Namespaces\" : [{ " + + "\"Namespace\" : \"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" " + + "}, " + + "{ " + + "\"Prefix\" : \"md\", " + + "\"Namespace\" : \"urn:example:med:schemas:record\" " + + "} " + + "], " + + "\"XPath\" : \"md:record/md:patient/md:patientDoB\" " + + "} " + + "} " + + "] " + + "} " + + "} " + + "} "; + + + + // test various ways that request might be empty + @Test + public void testEmptyRequest() { + // null request + try { + request = JSONRequest.load((String)null); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // empty request + try { + request = JSONRequest.load((String)""); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)" "); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // empty JSON request + try { + request = JSONRequest.load((String)"{}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{{}}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // garbage input + try { + request = JSONRequest.load((String)"Some non-JSON string"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{something non-JSON}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // bad syntax (Request with no content) + try { + request = JSONRequest.load((String)"{\"Request\"}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // bad syntax (no :field after Request) + try { + request = JSONRequest.load((String)"{\"Request\" : }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // bad syntax (no " around Request) + try { + request = JSONRequest.load((String)"{Request}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // empty content in Request + try { + request = JSONRequest.load((String)"{\"Request\" : \"\"}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // content is not an object + try { + request = JSONRequest.load((String)"{\"Request\" : \"CombinedDecision\" : true }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // too many } at end + // Jackson parser does not treat this as an error + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\"}}}}}"); + assertEquals("{requestDefaults={xpatherVersion=http://www.w3.org/TR/1999/REC-xpath-19991116},returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // too few } at end + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\" }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // misplaced } in middle + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : } \"http://www.w3.org/TR/1999/REC-xpath-19991116\"}}}}}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + } + + + + // Test double braces around request + @Test + public void testDoubleBraces() { + + try { + request = JSONRequest.load((String)"{{\"Request\" }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{{\"Request\" : }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{{\"Request\" : {\"CombinedDecision\" : true }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + + // test elements missing from top-level Request and arrays where single elements should be + @Test + public void testMissingFields() { + + // Request containing empty array + try { + request = JSONRequest.load((String)"{\"Request\" : []}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // array of one element + try { + request = JSONRequest.load((String)"{\"Request\" : [{\"CombinedDecision\" : true }]}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // correctly formatted empty request gives request with defaults set + try { + request = JSONRequest.load((String)"{\"Request\" : { }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // space in front of name (inside quotes) + try { + request = JSONRequest.load((String)"{\" Request\" : {\"XPathVersion\" : \"http://some/other/default/uri\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // space at end of name (inside quotes) + try { + request = JSONRequest.load((String)"{\"Request \" : {\"XPathVersion\" : \"http://some/other/default/uri\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // space in front of value (inside quotes) - valid String but not valid URI + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \" http://some/other/default/uri\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // space at end of value (inside quotes) - valid String but not valid URI + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"http://some/other/default/uri \" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + // test just one of each top-level element. + // For simple elements also test for incorrect type + @Test + public void testTopLevelElements() { + + // empty request + try { + request = JSONRequest.load((String)"{\"Request\" : {}}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // ReturnPolicyIdList + try { + request = JSONRequest.load((String)"{\"Request\" : {\"ReturnPolicyIdList\" : true }}"); + assertEquals("{returnPolicyIdList=true,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"ReturnPolicyIdList\" : \"abc\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load((String)"{\"Request\" : {\"ReturnPolicyIdList\" : 123 }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // CombinedDecision + try { + request = JSONRequest.load((String)"{\"Request\" : { \"CombinedDecision\" : true }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=true}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"CombinedDecision\" : \"abc\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load((String)"{\"Request\" : {\"CombinedDecision\" : 123 }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // XPathVersion + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"http://some/other/default/uri\" }}"); + assertEquals("{requestDefaults={xpatherVersion=http://some/other/default/uri},returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : true }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : 123 }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"not a uri\" }}"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Category + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=another-custom-cat},xmlId=anotherXmlId}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AccessSubject + try { + request = JSONRequest.load((String)"{\"Request\" : { \"AccessSubject\":{ }}}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action + try { + request = JSONRequest.load((String)"{\"Request\" : { \"Action\":{ }}}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Resource\":{ }}}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Environment\":{ } }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:environment}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,multiRequests=[{requestAttributesReferences=[{referenceId=foo1}{referenceId=bar1}]}{requestAttributesReferences=[{referenceId=foo2}{referenceId=bar2}]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequest with 1 + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : [\"bar2\"]" + + "}]" + + "} } }"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,multiRequests=[{requestAttributesReferences=[{referenceId=bar2}]}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequest with RequestReferences with no ReferenceId + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : []" + + "}]" + + "} } }"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // MultiRequests with no RequestReference + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": []" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests with something other than RequestReference + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"SomeOtherAttribute\": 123" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests with single RequestReference rather than array + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": " + + "{" + + "\"ReferenceId\" : []" + + "}" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests with RequestReference containing single element instead of array + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : \"foo1\"" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : {\"foo1\"}" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests with component that is not a RequestReference + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"SomeOtherAttribute\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests with component that is not a RequestReference + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]," + + "\"SomeOtherAttribute\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequest with unknown elements (in addition to RequestReference) + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"SomeOtherAttribute\": 123," + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequest with RequestReferences with ReferenceId NOT a string + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : [ true ]" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{" + + "\"ReferenceId\" : [ 123 ]" + + "}]" + + "} } }"); + fail("Request should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Cannot test with ReferenceId that is NOT referring to a Category object Id property because we may not have read the Category objects yet. + // Need to leave this up to the PDP. + + + // extra elements in top-level + try { + request = JSONRequest.load((String)"{\"Request\" : {}, \"unknownElement\" : false, \"unk2\" : \"abc\", \"unk3\" : 123 }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // extra elements in Request + try { + request = JSONRequest.load((String)"{\"Request\" : {\"XPathVersion\" : \"http://www.w3.org/TR/1999/REC-xpath-19991116\", \"unknownElement\" : false }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + + // Test with every field filled in with multiple values where appropriate + @Test + public void testAllFieldsRequest() { + + // convert Response to JSON + try { + request = JSONRequest.load(allFieldsRequest); + assertEquals("{requestDefaults={xpatherVersion=http://www.w3.org/TR/1999/REC-xpath-19991116},returnPolicyIdList=true,combinedDecision=true,requestAttributes=[{super={category=custom-category,attributes=[{attributeId=document-id,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#integer,value=123}],includeInResults=false}{attributeId=document-url,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=http://somewhere.over.the.com/rainbow}],includeInResults=false}{attributeId=page-list,category=custom-category,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=1.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=2.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=4.5}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=3.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=2.0}{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=1.0}],includeInResults=false}]},xmlId=customId}{super={category=another-custom-cat},xmlId=anotherXmlId}{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject},contentRoot=[catalog: null]}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource},contentRoot=[catalog: null]}],multiRequests=[{requestAttributesReferences=[{referenceId=foo1}{referenceId=bar1}]}{requestAttributesReferences=[{referenceId=foo2}{referenceId=bar1}]}]}" + , request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // convert example request from spec + try { + request = JSONRequest.load(exampleFromSpec); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,attributes=[{attributeId=subject-id,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Andreas}],includeInResults=false}{attributeId=location,category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Gamla Stan}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,attributes=[{attributeId=action-id,category=urn:oasis:names:tc:xacml:3.0:attribute-category:action,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#anyURI,value=http://www.xacml.eu/buy}],includeInResults=false}]}}{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=book-title,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=Learn German in 90 days}],includeInResults=false}{attributeId=currency,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#string,value=SEK}],includeInResults=false}{attributeId=price,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=http://www.w3.org/2001/XMLSchema#double,value=123.34}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // convert example request from spec containing XPAthExpression + try { + request = JSONRequest.load(xPathExampleFromSpec); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,attributes=[{attributeId=urn:oasis:names:tc:xacml:3.0:content-selector,category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource,values=[{dataTypeId=urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression,value={path=md:record/md:patient/md:patientDoB,Namespace={[{md,urn:example:med:schemas:record}{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}]},status=null,xpathExpressionWrapped=null},xpathCategory=urn:oasis:names:tc:xacml:3.0:attribute-category:resource}],includeInResults=false}]}}]}", request.toString()); + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + } + + + + // Duplicates - Each element duplicated + @Test + public void testDuplicates() { + // duplicate Request + try { + request = JSONRequest.load((String)"{\"Request\" : {}, \"Request\" : {}}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"ReturnPolicyIdList\" : true, \"ReturnPolicyIdList\" : true }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : { \"CombinedDecision\" : true, \"CombinedDecision\" : true }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "]," + + "\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "] }}"); + assertEquals("{returnPolicyIdList=false,combinedDecision=false,requestAttributes=[{super={category=another-custom-cat},xmlId=anotherXmlId}]}", request.toString()); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "] }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "} " + + "] }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Category\": [{ " + + "\"CategoryId\": \"another-custom-cat\", " + + "\"Id\" : \"anotherXmlId\", " + + "\"Attribute\" : []" + + "\"Attribute\" : []" + + "} " + + "] }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // AccessSubject + try { + request = JSONRequest.load((String)"{\"Request\" : { \"AccessSubject\":{ }, \"AccessSubject\":{ }}}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Action + try { + request = JSONRequest.load((String)"{\"Request\" : { \"Action\":{ }, \"Action\":{ }}}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Resource + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Resource\":{ }, \"Resource\":{ }}}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Environment + try { + request = JSONRequest.load((String)"{\"Request\" : {\"Environment\":{ }, \"Environment\":{ } }}"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // MultiRequests + + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "}," + + "\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]," + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + try { + request = JSONRequest.load((String)"{\"Request\" : {\"MultiRequests\" : {" + + "\"RequestReference\": [" + + "{ " + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "\"ReferenceId\" : [\"foo1\",\"bar1\"]" + + "}," + + "{" + + "\"ReferenceId\" : [\"foo2\",\"bar2\"]" + + "}]" + + "} } }"); + fail("Unknown element should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + } + + +} diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseConformanceTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseConformanceTest.java new file mode 100644 index 000000000..601a4629b --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseConformanceTest.java @@ -0,0 +1,370 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeCategory; +import com.att.research.xacml.api.IdReference; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.util.ListUtil; +/** + * Test JSON Response convert to object - Conformance tests + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * Note: some of the validation tests comparing the XML-derived Results to the JSON-derived Results are high-level comparisons of Collections. + * When this class was first created that was sufficient to pass all Conformance tests. + * However if this sees a failure in a Conformance test, those validations may need to be upgraded to look at the individual data elements to see what is wrong. + * + * + */ +public class ResponseConformanceTest { + + // where to find the conformance test XML files + private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4"; + + // The request object output from each test conversion from JSON string + Response response; + + + + + + // test just one of each top-level element. + // For simple elements also test for incorrect type + @Test + public void testConformanceResponses() { + + List<File> filesInDirectory = null; + + File conformanceDirectory = null; + + File currentFile = null; + + try { + conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH); + filesInDirectory = getRequestsInDirectory(conformanceDirectory); + } catch (Exception e) { + fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e); + } + + // run through each XML file + // - load the file from XML into an internal Response object + // - generate the JSON representation of that Response object + // - load that JSON representation into a new Response object + // - compare the 2 Request objects + Response xmlResponse = null; + Response jsonResponse = null; + try { + for (File f : filesInDirectory) { + currentFile = f; + +//// This is a simple way to select just one file for debugging - comment out when not being used +//if ( ! f.getName().equals("IIIA030Response.xml") && ! f.getName().equals("IIIA330Response.xml")) { continue; } + +// during debugging it is helpful to know what file it is starting to work on +// System.out.println("starting file="+currentFile.getName()); + + try { + // load XML into a Response object + xmlResponse = DOMResponse.load(f); + } catch (Exception e) { + // if XML does not load, just note it and continue with next file + System.out.println("XML file did not load: '" + f.getName() + " e=" + e); + continue; + } + + // some tests have JSON response files to load, most do not + String jsonFileName = f.getName().replace(".xml", ".json"); + File jsonFile = new File(conformanceDirectory, jsonFileName); + + if (jsonFile.exists()) { +//System.out.println("found file "+jsonFile.getName()); + // json version exists in file, so load it + jsonResponse = JSONResponse.load(jsonFile); + } else { + // json does not exist in file, so create it from the XML response using a String intermediate version + String jsonResponseString = JSONResponse.toString(xmlResponse, false); +//System.out.println(jsonResponseString); +//System.out.println(JSONResponse.toString(xmlResponse, true)); + + jsonResponse = JSONResponse.load(jsonResponseString); + } + + +//System.out.println(JSONResponse.toString(xmlResponse, true)); + + + + + // compare the two Response objects + + // compare results + assertEquals(xmlResponse.getResults().size(), jsonResponse.getResults().size()); + + if (xmlResponse.getResults().size() == 0) { + fail("neither XML nor JSON response have any Results"); + } + + + // Results are an un-ordered Collection. + // There is no identifying information that is unique to a specific Result. + // If there are more than one we cannot be sure which one corresponds with which. + // The best we can do is say that one or more in the first list do not match any in the second list + if (xmlResponse.getResults().size() > 1) { + for (Result xmlResult : xmlResponse.getResults()) { + boolean found = false; + for (Result jsonResult : jsonResponse.getResults()) { + if (xmlResult.equals(jsonResult)) { + found = true; + break; + } + } + if (found) { + continue; + } + // no match found + System.out.println("No match for XML in " + f.getName()); + System.out.println("XML =" + xmlResult.toString()); + for (Result jsonResult : jsonResponse.getResults()) { + System.out.println("JSON="+ jsonResult.toString()); + } + fail("JSON Response has no match for XML Result: " + xmlResult.toString()); + } + // we've done the best we can for multiple decisions, so go to next file + continue; + } + + // single Result in each + Result xmlResult = xmlResponse.getResults().iterator().next(); + Result jsonResult = jsonResponse.getResults().iterator().next(); + + // The following sections have not given us trouble, so checking is very high-level. + // If we see a problem in one of these elements, the single line will need to be replaced with detailed examination of the objects. + assertEquals(f.getName() + " Decision", xmlResult.getDecision(), jsonResult.getDecision()); + assertEquals(f.getName() + " Status", xmlResult.getStatus(), jsonResult.getStatus()); + + // Obligations + if (xmlResult.getObligations() != jsonResult.getObligations()) { + Collection<Obligation> xmlObligations = xmlResult.getObligations(); + Collection<Obligation> jsonObligations = jsonResult.getObligations(); + // if both are null we do not get here + if (xmlObligations == null || jsonObligations == null) { + fail(f.getName() + " Obligations has null \nXML="+xmlObligations + "\nJSON="+jsonObligations); + } + if (ListUtil.equalsAllowNulls(xmlObligations, jsonObligations) == false) { + // collections are not equal, so need to examine further +fail(f.getName() + " Obligation collections not equal\nXML="+xmlObligations + "\nJSON="+jsonObligations); + } + } + + // AssociatedAdvice + if (xmlResult.getAssociatedAdvice() != jsonResult.getAssociatedAdvice()) { + Collection<Advice> xmlAdvice = xmlResult.getAssociatedAdvice(); + Collection<Advice> jsonAdvice = jsonResult.getAssociatedAdvice(); + // if both are null we do not get here + if (xmlAdvice == null || jsonAdvice == null) { + fail(f.getName() + " Advice has null \nXML="+xmlAdvice + "\nJSON="+jsonAdvice); + } + if (ListUtil.equalsAllowNulls(xmlAdvice, jsonAdvice) == false) { + // collections are not equal, so need to examine further +fail(f.getName() + " Advice collections not equal\nXML="+xmlAdvice + "\nJSON="+jsonAdvice); + } + } + + + + // check Attributes in more detail + Collection<AttributeCategory> xmlAttributes = xmlResult.getAttributes(); + Collection<AttributeCategory> jsonAttributes = jsonResult.getAttributes(); + if (xmlAttributes == null && jsonAttributes != null || + xmlAttributes != null && jsonAttributes == null) { + fail(f.getName() + " XML Attributes="+xmlAttributes + " but JSON Attributes=" + jsonAttributes); + } + if (xmlAttributes != null) { + // both are non-null + if (xmlAttributes.size() != jsonAttributes.size()) { + String xmlAttributesString = "XML categorys="; + for (AttributeCategory ac : xmlAttributes) { + xmlAttributesString += " " + ac.getCategory().stringValue(); + } + String jsonAttributesString = "JSON categorys="; + for (AttributeCategory ac : jsonAttributes) { + jsonAttributesString += " " + ac.getCategory().stringValue(); + } + fail(f.getName() + " XML and JSON have different number of Category elements: " + xmlAttributesString + ", " + jsonAttributesString); + } + + // Attribute collections are the same size but may be in different orders. + // for each XML category try to find the corresponding JSON category. + // ASSUME that each category only shows up once!!!! + for (AttributeCategory xmlAttributeCategory : xmlAttributes) { + boolean attributeCategoryFound = false; + for (AttributeCategory jsonAttributeCategory : jsonAttributes) { + if (xmlAttributeCategory.equals(jsonAttributeCategory)) { + attributeCategoryFound = true; + break; + } + // not an exact match, but if same CategoryId then need to check individual Attribute objects + if (xmlAttributeCategory.getCategory().equals(jsonAttributeCategory.getCategory())) { + // same category + if (xmlAttributeCategory.getAttributes().size() != jsonAttributeCategory.getAttributes().size()) { + System.out.println("XML =" + xmlAttributeCategory.getAttributes()); + System.out.println("JSON=" + jsonAttributeCategory.getAttributes()); + fail(f.getName() + " Attributes Category '" + xmlAttributeCategory.getCategory().stringValue() + "' size mismatch; XML="+ + xmlAttributeCategory.getAttributes().size() +", JSON=" + jsonAttributeCategory.getAttributes().size()); + } + for (Attribute xmlAttr : xmlAttributeCategory.getAttributes()) { + boolean attributeFound = false; + for (Attribute jsonAttr : jsonAttributeCategory.getAttributes()) { + if (xmlAttr.equals(jsonAttr)) { + attributeFound = true; + break; + } + } + + if (attributeFound) { + // check next XML attribute + continue; + } + System.out.println("Attribute not found in JSON, Category="+xmlAttributeCategory.getCategory()); + System.out.println("XML Attribute ="+ xmlAttr); + System.out.println("JSON Attributes=" + jsonAttributeCategory.toString()); + fail(f.getName() + " Attribute not found in JSON, Category=" + xmlAttributeCategory.getCategory() + + "/nXML Attribute="+xmlAttr+ + "\nJSON Category Attributes="+jsonAttributeCategory.toString()); + } + + + + } + } + if (attributeCategoryFound) { + continue; + } + fail("XML Category not found in JSON; xml="+xmlAttributeCategory.toString()); + } + + } + + // PolicyIdentifiers + if (xmlResult.getPolicyIdentifiers() != jsonResult.getPolicyIdentifiers()) { + Collection<IdReference> xmlIdReferences = xmlResult.getPolicyIdentifiers(); + Collection<IdReference> jsonIdReferences = jsonResult.getPolicyIdentifiers(); + // if both are null we do not get here + if (xmlIdReferences == null || jsonIdReferences == null) { + fail(f.getName() + " PolicyIdentifiers has null \nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences); + } + if (ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences) == false) { + // collections are not equal, so need to examine further +fail(f.getName() + " PolicyIdentifiers collections not equal\nXML="+xmlIdReferences+ "\nJSON="+jsonIdReferences); + } + } + + // PolicySetIdentifiers + if (xmlResult.getPolicySetIdentifiers() != jsonResult.getPolicySetIdentifiers()) { + Collection<IdReference> xmlIdReferences = xmlResult.getPolicySetIdentifiers(); + Collection<IdReference> jsonIdReferences = jsonResult.getPolicySetIdentifiers(); + // if both are null we do not get here + if (xmlIdReferences == null || jsonIdReferences == null) { + fail(f.getName() + " PolicySetIdentifiers has null \nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences); + } + if (ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences) == false) { + // collections are not equal, so need to examine further +fail(f.getName() + " PolicySetIdentifiers collections not equal\nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences); + } + } + + + } + + } catch (Exception e) { + fail ("Failed test with '" + currentFile.getName() + "', e=" + e); + } + + + } + + // + // HELPER to get list of all Request files in the given directory + // + + private List<File> getRequestsInDirectory(File directory) { + List<File> fileList = new ArrayList<File>(); + + File[] fileArray = directory.listFiles(); + for (File f : fileArray) { + if (f.isDirectory()) { + List<File> subDirList = getRequestsInDirectory(f); + fileList.addAll(subDirList); + } + if (f.getName().endsWith("Response.xml")) { + fileList.add(f); + } + } + return fileList; + + } + +} + + + + + +/* + * +This is a place to copy the really long output from test rigs that need to be manually edited for readability.... + + + +{"Response":[{"Status":{"StatusCode":{"Value":"urn:oasis:names:tc:xacml:1.0:status:ok"}},"Obligations":[{"Id":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:obligation-1","AttributeAssignment":[ +{"Value":"assignment1","DataType":"string","AttributeId":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment1"}, +{"Value":{"Namespaces":[{"Namespace":"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"},{"Namespace":"http://www.w3.org/2001/XMLSchema-instance","Prefix":"xsi"}], + "XPathCategory":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource", + "XPath":"//md:records/md:record"}, + "DataType":"xpathExpression", + "AttributeId":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment2"}]}],"Decision":"Permit"}]} + + + +*/ + + + + + diff --git a/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseTest.java b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseTest.java new file mode 100644 index 000000000..12da12cbf --- /dev/null +++ b/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/json/ResponseTest.java @@ -0,0 +1,2297 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-XACML + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.xacml.test.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.math.BigInteger; + +import org.junit.Ignore; +import org.junit.Test; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Decision; +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.StdAttribute; +import com.att.research.xacml.std.StdAttributeCategory; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdIdReference; +import com.att.research.xacml.std.StdMutableAdvice; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.StdMutableAttributeAssignment; +import com.att.research.xacml.std.StdMutableMissingAttributeDetail; +import com.att.research.xacml.std.StdMutableObligation; +import com.att.research.xacml.std.StdMutableResponse; +import com.att.research.xacml.std.StdMutableResult; +import com.att.research.xacml.std.StdMutableStatus; +import com.att.research.xacml.std.StdMutableStatusDetail; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.StdVersion; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.StringNamespaceContext; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.json.JSONResponse; +import com.att.research.xacml.std.json.JSONStructureException; + +/** + * Test JSON Responses + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class ResponseTest { + + String jsonResponse; + + StdMutableResponse response; + + StdMutableResult result; + + StdMutableStatus status; + + + // Note: Initially test responses without Obligations, Associated Advice, Attributes, or PolicyIdentifier + + + @Test + public void testEmptyAndDecisions() { + // null response + try { + jsonResponse = JSONResponse.toString(null, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // empty response (no Result object) + response = new StdMutableResponse(); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // just decision, no status + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // just status (empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // just status (non-empty), no decision + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setStatus(status); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // test other decisions without Status + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.DENY); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Deny\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.NOTAPPLICABLE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"NotApplicable\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENY); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Indeterminate{D}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Indeterminate{DP}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.INDETERMINATE_PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Indeterminate{P}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - success + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + StdMutableResult result2 = new StdMutableResult(); + result2.setDecision(Decision.DENY); + response.add(result2); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\"},{\"Decision\":\"Deny\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // test Multiple Decisions - one success and one error + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + response.add(result); + result2 = new StdMutableResult(); + result2.setDecision(Decision.INDETERMINATE); + response.add(result2); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\"},{\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // Test with every field filled in with multiple values where appropriate + @Ignore //@Test + public void testAllFieldsResponse() { + + // fully-loaded multiple response + + StdMutableResponse response = new StdMutableResponse(); + // create a Status object + StdMutableStatus status = new StdMutableStatus(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("some status message"); + StdMutableStatusDetail statusDetailIn = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "doh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_INTEGER.getId(), "5432")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.setAttributeId(XACML3.ID_ACTION_PURPOSE); + mad.setCategory(XACML3.ID_ATTRIBUTE_CATEGORY_ACTION); + mad.setDataTypeId(XACML3.ID_DATATYPE_STRING); + mad.setIssuer("an Issuer"); + statusDetailIn.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetailIn); + // create a single result object + StdMutableResult result = new StdMutableResult(status); + // set the decision + result.setDecision(Decision.INDETERMINATE); + // put the Result into the Response + response.add(result); + + + // create a new Result with a different Decision + status = new StdMutableStatus(StdStatusCode.STATUS_CODE_OK); + result = new StdMutableResult(status); + result.setDecision(Decision.DENY); + + StdMutableObligation obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer2", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned"))); + result.addObligation(obligation); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_SUBJECT_CATEGORY_INTERMEDIARY_SUBJECT); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer3", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer4", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer"))); + result.addObligation(obligation); + + + StdMutableAdvice advice = new StdMutableAdvice(); + advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"))); + advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "advice-issuerNoCategory", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Crusty"))); + result.addAdvice(advice); + + + response.add(result); + + + // create a new Result with a different Decision + // add Child/minor status codes within the main status + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + + status = new StdMutableStatus(statusCode); + + + result = new StdMutableResult(status); + result.setDecision(Decision.PERMIT); + + + + + // add attribute list in result + Identifier categoryIdentifier = new IdentifierImpl("firstCategory"); + Attribute[] attrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "EIssue", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), null, true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(attrList))); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + + + // add PolicyIdentifierList to result + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + + response.add(result); + + // convert Response to JSON + try { + jsonResponse = JSONResponse.toString(response, false); +System.out.println(jsonResponse); +//System.out.println(JSONResponse.toString(response, true)); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusMessage\":\"some status message\",\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\\\\\\\" AttributeId=\\\\\\\"urn:oasis:names:tc:xacml:2.0:action:purpose\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\" Issuer=\\\\\\\"an Issuer\\\\\\\"><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\">doh</AttributeValue><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#integer\\\\\\\">5432</AttributeValue><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\">meh</AttributeValue></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"},{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer2\",\"Value\":\"Ned\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]},{\"Id\":\"urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer3\",\"Value\":\"Maggie\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer4\",\"Value\":\"Homer\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Deny\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"advice-issuer1\",\"Value\":\"Apu\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"advice-issuerNoCategory\",\"Value\":\"Crusty\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]},{\"Status\":{\"StatusCode\":{\"StatusCode\":{\"StatusCode\":{\"StatusCode\":{\"Value\":\"childChildChildStatusCode\"},\"Value\":\"childChildStatusCode\"},\"Value\":\"child1StatusCode\"},\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"CIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent3\"},{\"Issuer\":\"DIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent4\"},{\"Issuer\":\"EIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent5\"},{\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrNoIssuer\"}]},{\"CategoryId\":\"secondCategory\",\"Attribute\":[{\"Issuer\":\"AIssue2\",\"Value\":\"Apu2\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent12\"},{\"Issuer\":\"CIssue2\",\"Value\":\"Der2\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent32\"}]}],\"Decision\":\"Permit\",\"PolicyIdentifier\":{\"PolicyIdReference\":[{\"Id\":\"idRef1\",\"Version\":\"1.2.3\"},{\"Id\":\"idRef2_NoVersion\"}],\"PolicySetIdReference\":[{\"Id\":\"idSetRef1\",\"Version\":\"4.5.6.7.8.9.0\"},{\"Id\":\"idSetRef2_NoVersion\"}]}}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // combinations of Status values with Decision values + @Test + public void testDecisionStatusMatch() { + // the tests in this method use different values and do not change structures, so we can re-use the objects + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + response.add(result); + + // StatusCode = OK + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + result.setDecision(Decision.PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},\"Decision\":\"Deny\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},\"Decision\":\"NotApplicable\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + + + + // StatusCode = SyntaxError + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + result.setDecision(Decision.PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"}},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"}},\"Decision\":\"Indeterminate{D}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"}},\"Decision\":\"Indeterminate{DP}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"}},\"Decision\":\"Indeterminate{P}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // StatusCode = ProcessingError + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + result.setDecision(Decision.PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"}},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"}},\"Decision\":\"Indeterminate{D}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"}},\"Decision\":\"Indeterminate{DP}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"}},\"Decision\":\"Indeterminate{P}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // StatusCode = MissingAttribute + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + result.setDecision(Decision.PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.NOTAPPLICABLE); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + result.setDecision(Decision.INDETERMINATE); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"}},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENY); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"}},\"Decision\":\"Indeterminate{D}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_DENYPERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"}},\"Decision\":\"Indeterminate{DP}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + result.setDecision(Decision.INDETERMINATE_PERMIT); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"}},\"Decision\":\"Indeterminate{P}\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + // tests related to Status and its components + @Ignore //@Test + public void testStatus() { + // Status with no StatusCode - error + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Status with StatusMessage when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail when OK + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_OK); + StdMutableStatusDetail statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Status with StatusMessage when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:syntax-error\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Status with StatusMessage when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:processing-error\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + // Status with StatusMessage when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with empty StatusDetail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"}},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // Status with StatusDetail with empty detail when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + StdMutableMissingAttributeDetail mad = new StdMutableMissingAttributeDetail(); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Status with StatusDetail with valid detail with no value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:1.0:action\\\\\\\" AttributeId=\\\\\\\"mad\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\"></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:1.0:action\\\\\\\" AttributeId=\\\\\\\"mad\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\"><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\">meh</AttributeValue></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Status with StatusDetail with array valid detail with value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:1.0:action\\\\\\\" AttributeId=\\\\\\\"mad\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\"><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\">meh</AttributeValue><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\">nu?</AttributeValue></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Status with StatusDetail with valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_INTEGER.getId()); + mad.addAttributeValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111))); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:1.0:action\\\\\\\" AttributeId=\\\\\\\"mad\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\"><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#integer\\\\\\\">1111</AttributeValue></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + e.printStackTrace(pw); + + + fail("operation failed, e="+e + sw.toString()); + } + + // Status with StatusDetail with array valid detail with Integer value when MissingAttribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111))); + mad.addAttributeValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(2222))); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<MissingAttributeDetail Category=\\\\\\\"urn:oasis:names:tc:xacml:1.0:action\\\\\\\" AttributeId=\\\\\\\"mad\\\\\\\" DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#string\\\\\\\"><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#integer\\\\\\\">1111</AttributeValue><AttributeValue DataType=\\\\\\\"http://www.w3.org/2001/XMLSchema#integer\\\\\\\">2222</AttributeValue></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + +// StringNamespaceContext snc = new StringNamespaceContext(); +// try { +// snc.add("defaultURI"); +// snc.add("md", "referenceForMD"); +// } catch (Exception e) { +// fail("unable to create NamespaceContext e="+e); +// } +// XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); +// +//TODO - assume that we will never try to pass back an XPathExpression in a MissingAttributeDetail - it doesn't make sense and is unclear how to put into XML +// // Status with StatusDetail with valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// jsonResponse = JSONResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<AttributeValue>1111</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } +// +// // Status with StatusDetail with array valid detail with XPathExpression value when MissingAttribute +// response = new StdMutableResponse(); +// result = new StdMutableResult(); +// status = new StdMutableStatus(); +// status.setStatusCode(StdStatusCode.STATUS_CODE_MISSING_ATTRIBUTE); +// statusDetail = new StdMutableStatusDetail(); +// mad = new StdMutableMissingAttributeDetail(); +// mad.setAttributeId(new IdentifierImpl("mad")); +// mad.setCategory(XACML3.ID_ACTION); +// mad.setDataTypeId(DataTypes.DT_STRING.getId()); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId1"))); +// mad.addAttributeValue(new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategoryId2"))); +// statusDetail.addMissingAttributeDetail(mad); +// status.setStatusDetail(statusDetail); +// result.setStatus(status); +// result.setDecision(Decision.INDETERMINATE); +// response.add(result); +// try { +// jsonResponse = JSONResponse.toString(response, false); +// assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:missing-attribute\"},\"StatusDetail\":\"<AttributeValue>1111</AttributeValue><AttributeValue>2222</AttributeValue><Category>urn:oasis:names:tc:xacml:1.0:action</Category><AttributeId>mad</AttributeId><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></MissingAttributeDetail>\"},\"Decision\":\"Indeterminate\"}]}", jsonResponse); +// } catch (Exception e) { +// fail("operation failed, e="+e); +// } + +//TODO - try with other data types, esp XPathExpression + + // Status with StatusDetail with array valid detail with value when SyntaxError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_SYNTAX_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Status with StatusDetail with array valid detail with value when ProcessingError + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + status.setStatusCode(StdStatusCode.STATUS_CODE_PROCESSING_ERROR); + statusDetail = new StdMutableStatusDetail(); + mad = new StdMutableMissingAttributeDetail(); + mad.setAttributeId(new IdentifierImpl("mad")); + mad.setCategory(XACML3.ID_ACTION); + mad.setDataTypeId(DataTypes.DT_STRING.getId()); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "meh")); + mad.addAttributeValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "nu?")); + statusDetail.addMissingAttributeDetail(mad); + status.setStatusDetail(statusDetail); + result.setStatus(status); + result.setDecision(Decision.INDETERMINATE); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // Status with nested child StatusCodes (child status containing child status containing...) + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode")); + StdStatusCode statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"StatusCode\":{\"Value\":\"child1StatusCode\"},\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + response = new StdMutableResponse(); + result = new StdMutableResult(); + status = new StdMutableStatus(); + StdStatusCode childChildChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildChildStatusCode")); + StdStatusCode childChildStatusCode = new StdStatusCode(new IdentifierImpl("childChildStatusCode"), childChildChildStatusCode); + child1StatusCode = new StdStatusCode(new IdentifierImpl("child1StatusCode"), childChildStatusCode); + statusCode = new StdStatusCode(XACML3.ID_STATUS_OK, child1StatusCode); + status = new StdMutableStatus(statusCode); + status.setStatusMessage("I'm ok, you're ok"); + result.setStatus(status); + result.setDecision(Decision.PERMIT); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Status\":{\"StatusCode\":{\"StatusCode\":{\"StatusCode\":{\"StatusCode\":{\"Value\":\"childChildChildStatusCode\"},\"Value\":\"childChildStatusCode\"},\"Value\":\"child1StatusCode\"},\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"},\"StatusMessage\":\"I'm ok, you're ok\"},\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + @Ignore //@Test + public void testObligations() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableObligation obligation; + + // test Obligation single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // obligation missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Bart\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + null)); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - missing DataType + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111)))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":1111,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:record\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Lisa\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer1\",\"Value\":\"Maggie\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111)))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(2222)))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "obligation-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(3333)))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"obligation-issuer1\",\"Value\":1111,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer1\",\"Value\":2222,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"obligation-issuer1\",\"Value\":3333,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + obligation = new StdMutableObligation(); + obligation.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + obligation.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addObligation(obligation); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Obligations\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:record\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:hospital\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + } + + + + + @Ignore //@Test + public void testAdvice() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + XPathExpressionWrapper xpathExpressionWrapper2 = new XPathExpressionWrapper(snc, "//md:hospital"); + + StdMutableAdvice Advice; + + // test Advice single decision no attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\"}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Advice missing Id + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + + + // AttributeAssignment - with AttributeId, Value, Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - with AttributeId, Value, no Category, DataType, Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + null, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Bart\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Missing AttributeId + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + null, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // AttributeAssignment - Missing Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + null)); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":\"\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - missing DataType + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(null, "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - missing issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // AttributeAssignment - Integer type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111)))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":1111,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - XPathExpression type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:record\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + + // + // Technically arrays cannot occur in Obligations and Advice elements. The XML spec boils down to the following definition: + // <Obligation (attributes of the obligation) > + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // <AttributeAssignment (attributes of this assignment) >value</AttributeAssignment> + // : + // </Obligation + // which means that there may be multiple AttributeAssignments but each one has only one value. + // This differs from the Attributes section in which each <Attribute> may have multiple <AttributeValue> elements. + // For Obligations and Advice we can simulate an array by having multiple AttributeAssignment elements with the same Category, Id and Issuer. + // + + // AttributeAssignment - Multiple values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Lisa"))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Maggie"))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Bart\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Lisa\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"Advice-issuer1\",\"Value\":\"Maggie\",\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // AttributeAssignment - Multiple Integer values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(1111)))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(2222)))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + "Advice-issuer1", + new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(3333)))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Issuer\":\"Advice-issuer1\",\"Value\":1111,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"Advice-issuer1\",\"Value\":2222,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Issuer\":\"Advice-issuer1\",\"Value\":3333,\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // Multiple XPathExpression values with same Category and Id (one way of doing array) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + Advice = new StdMutableAdvice(); + Advice.setId(XACML3.ID_ACTION_IMPLIED_ACTION); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("SimpleXPathCategory")))); + Advice.addAttributeAssignment(new StdMutableAttributeAssignment( + XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + XACML3.ID_SUBJECT, + null, + new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper2, new IdentifierImpl("SimpleXPathCategory")))); + result.addAdvice(Advice); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"AssociatedAdvice\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:implied-action\",\"AttributeAssignment\":[{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:record\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"},{\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"SimpleXPathCategory\",\"XPath\":\"//md:hospital\"},\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"urn:oasis:names:tc:xacml:1.0:subject\"}]}]}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + + + + + + + + + + // Attributes tests + @Ignore //@Test + public void testAttributes() { + + // create an XPathExpression for use later + StringNamespaceContext snc = new StringNamespaceContext(); + try { + snc.add("defaultURI"); + snc.add("md", "referenceForMD"); + } catch (Exception e) { + fail("unable to create NamespaceContext e="+e); + } + XPathExpressionWrapper xpathExpressionWrapper = new XPathExpressionWrapper(snc, "//md:record"); + + + Identifier categoryIdentifier; + List<Attribute> attrList = new ArrayList<Attribute>(); + StdMutableAttribute mutableAttribute; + + // Attr list with no entries + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // multiple attributes + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "EIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"BIssue\",\"Value\":\"P10Y4M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"AttributeId\":\"attrIdent2\"},{\"Issuer\":\"CIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent3\"},{\"Issuer\":\"DIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent4\"},{\"Issuer\":\"EIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent5\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // IncludeInResult=false/true + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", false)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // Missing AttributeId (mandatory) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, null, new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Missing mandatory Value + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), null), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // Missing optional Issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // missing optional DataType + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(null, "Apu"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same id, same type different issuer + // (This is not an array of values because issuer is different) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "CIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"BIssue\",\"Value\":\"Bart\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"CIssue\",\"Value\":\"Simpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same id, same type different issuer + // (This is effectively an array of values, but we return them as separate values to the client) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Simpson"), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":\"Bart\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":\"Simpson\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":\"P10Y4M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"AIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // same Id, different types, different issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"BIssue\",\"Value\":\"P10Y4M\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"CIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"DIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"EIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent1\"},{\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + // different Id, different types, same issuer + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "AIssue"), "BIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"BIssue\",\"Value\":\"AIssue\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#yearMonthDuration\",\"AttributeId\":\"attrIdent2\"},{\"Issuer\":\"AIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent3\"},{\"Issuer\":\"AIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent4\"},{\"Issuer\":\"AIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent5\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // one Attribute of type XPathExpression (the only complex data type) + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<XPathExpressionWrapper>(DataTypes.DT_XPATHEXPRESSION.getId(), xpathExpressionWrapper, new IdentifierImpl("xpathCategory")), "AIssue", true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":{\"Namespaces\":[{\"Namespace\":\"referenceForMD\",\"Prefix\":\"md\"},{\"Namespace\":\"defaultURI\"}],\"XPathCategory\":\"xpathCategory\",\"XPath\":\"//md:record\"},\"DataType\":\"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // multiple sets of values + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + categoryIdentifier = new IdentifierImpl("firstCategory"); + attrList.clear(); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu"), "AIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent2"), new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M"), "BIssue", false)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent3"), new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432), "CIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent4"), new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true), "DIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent5"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), "EIssue", true)); + attrList.add(new StdAttribute(categoryIdentifier, new IdentifierImpl("attrNoIssuer"), new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567)), null, true)); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + categoryIdentifier = new IdentifierImpl("secondCategory"); + Attribute[] secondAttrList = { + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent12"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu2"), "AIssue2", true), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent22"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Abc2"), "BIssue2", false), + new StdAttribute(categoryIdentifier, new IdentifierImpl("attrIdent32"), new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Der2"), "CIssue2", true) }; + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, Arrays.asList(secondAttrList))); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":\"Apu\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"},{\"Issuer\":\"CIssue\",\"Value\":765.432,\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent3\"},{\"Issuer\":\"DIssue\",\"Value\":true,\"DataType\":\"http://www.w3.org/2001/XMLSchema#boolean\",\"AttributeId\":\"attrIdent4\"},{\"Issuer\":\"EIssue\",\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrIdent5\"},{\"Value\":4567,\"DataType\":\"http://www.w3.org/2001/XMLSchema#integer\",\"AttributeId\":\"attrNoIssuer\"}]},{\"CategoryId\":\"secondCategory\",\"Attribute\":[{\"Issuer\":\"AIssue2\",\"Value\":\"Apu2\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent12\"},{\"Issuer\":\"CIssue2\",\"Value\":\"Der2\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent32\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - same type + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Bart")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Homer")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Ned")); + + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":[\"Apu\",\"Bart\",\"Homer\",\"Ned\"],\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - compatible different types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567))); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567))); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Category\":[{\"CategoryId\":\"firstCategory\",\"Attribute\":[{\"Issuer\":\"AIssue\",\"Value\":[4567,765.432,4567],\"DataType\":\"http://www.w3.org/2001/XMLSchema#double\",\"AttributeId\":\"attrIdent1\"}]}],\"Decision\":\"Permit\"}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // array of values - incompatible different types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + attrList.clear(); + categoryIdentifier = new IdentifierImpl("firstCategory"); + mutableAttribute = new StdMutableAttribute(categoryIdentifier, new IdentifierImpl("attrIdent1"), (Collection<AttributeValue<?>>)null, "AIssue", true); + + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), "Apu")); + mutableAttribute.addValue(new StdAttributeValue<String>(DataTypes.DT_YEARMONTHDURATION.getId(), "P10Y4M")); + mutableAttribute.addValue(new StdAttributeValue<Double>(DataTypes.DT_DOUBLE.getId(), 765.432)); + mutableAttribute.addValue(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), true)); + mutableAttribute.addValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567))); + mutableAttribute.addValue(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), BigInteger.valueOf(4567))); + attrList.add(mutableAttribute); + result.addAttributeCategory(new StdAttributeCategory(categoryIdentifier, attrList)); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + } + + + + + + // PolicyIdentifier tests + @Ignore //@Test + public void testPolicyIdentifier() { + + StdIdReference policyIdentifier1 = null; + StdIdReference policyIdentifier2 = null; + StdIdReference policySetIdentifier1 = null; + StdIdReference policySetIdentifier2 = null; + + // multiple PolicyIdentifiers of both types + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"PolicyIdentifier\":{\"PolicyIdReference\":[{\"Id\":\"idRef1\",\"Version\":\"1.2.3\"},{\"Id\":\"idRef2_NoVersion\"}],\"PolicySetIdReference\":[{\"Id\":\"idSetRef1\",\"Version\":\"4.5.6.7.8.9.0\"},{\"Id\":\"idSetRef2_NoVersion\"}]}}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // PolicyIdentifier exists but has no IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policyIdentifier1 = null; + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // PolicySetIdentifier exists but has not IdReferences + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + policySetIdentifier1 = null; + result.addPolicyIdentifier(policySetIdentifier1); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + fail("Operation should throw exception"); + } catch (JSONStructureException e) { + // correct response + } catch (Exception e) { + fail ("Failed convert from JSON to object: " + e); + } + + // PolicyIdentifier with PolicyIdReference and no PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), StdVersion.newInstance("1.2.3")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicyIdentifier(policyIdentifier1); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"PolicyIdentifier\":{\"PolicyIdReference\":[{\"Id\":\"idRef1\",\"Version\":\"1.2.3\"}]}}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + + // PolicyIdentifier with no PolicyIdReference and with PolicySetIdReference + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + try { + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1"), StdVersion.newInstance("4.5.6.7.8.9.0")); + } catch (ParseException e1) { + fail("creating policyIds, e="+e1); + } + result.addPolicySetIdentifier(policySetIdentifier1); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"PolicyIdentifier\":{\"PolicySetIdReference\":[{\"Id\":\"idSetRef1\",\"Version\":\"4.5.6.7.8.9.0\"}]}}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + + + // IdReferences without version + response = new StdMutableResponse(); + result = new StdMutableResult(); + result.setDecision(Decision.PERMIT); + + policyIdentifier1 = new StdIdReference(new IdentifierImpl("idRef1"), null); + policyIdentifier2 = new StdIdReference(new IdentifierImpl("idRef2_NoVersion")); + policySetIdentifier1 = new StdIdReference(new IdentifierImpl("idSetRef1")); + policySetIdentifier2 = new StdIdReference(new IdentifierImpl("idSetRef2_NoVersion")); + + result.addPolicyIdentifier(policyIdentifier1); + result.addPolicyIdentifier(policyIdentifier2); + result.addPolicySetIdentifier(policySetIdentifier1); + result.addPolicySetIdentifier(policySetIdentifier2); + response.add(result); + try { + jsonResponse = JSONResponse.toString(response, false); + assertEquals("{\"Response\":[{\"Decision\":\"Permit\",\"PolicyIdentifier\":{\"PolicyIdReference\":[{\"Id\":\"idRef1\"},{\"Id\":\"idRef2_NoVersion\"}],\"PolicySetIdReference\":[{\"Id\":\"idSetRef1\"},{\"Id\":\"idSetRef2_NoVersion\"}]}}]}", jsonResponse); + } catch (Exception e) { + fail("operation failed, e="+e); + } + } + + +//TODO - the JSON and XML spec imply that the Result Attributes may include the Content (It is part of the UML) + + + // test indentation??? + + // order does not matter?? + +} + + + + + + + + + + + + + + + + |