From 91d04c64771832a0b8815ffbe1f0f9920320d94d Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 14 Feb 2017 19:41:00 -0500 Subject: Initial OpenECOMP policy/engine commit Change-Id: I7dbff37733b661643dd4d1caefa3d7dccc361b6e Signed-off-by: Pamela Dragosh --- .../policy/pdp/test/conformance/Conformance.java | 634 +++++++++++++++++++++ .../pdp/test/conformance/ConformancePIPEngine.java | 242 ++++++++ .../test/conformance/ConformanceRepository.java | 127 +++++ .../test/conformance/ConformanceScopeResolver.java | 121 ++++ .../pdp/test/conformance/ConformanceTest.java | 104 ++++ .../test/conformance/ConformanceTestEngine.java | 219 +++++++ .../test/conformance/ConformanceTestResult.java | 122 ++++ .../pdp/test/conformance/ConformanceTestSet.java | 180 ++++++ .../pdp/test/conformance/ResponseMatchResult.java | 137 +++++ .../pdp/test/conformance/ResultMatchResult.java | 136 +++++ 10 files changed, 2022 insertions(+) create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/Conformance.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformancePIPEngine.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceRepository.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceScopeResolver.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTest.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestEngine.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestResult.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestSet.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResponseMatchResult.java create mode 100644 ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResultMatchResult.java (limited to 'ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance') diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/Conformance.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/Conformance.java new file mode 100644 index 000000000..ffd867977 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/Conformance.java @@ -0,0 +1,634 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.api.AttributeCategory; +import com.att.research.xacml.api.AttributeValue; +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; + +/** + * Conformance is an application that runs a ConformanceTestSet and dumps results comparing the actual and + * expected results. + * + * TO RUN in Eclipse: + * This is run as a Java Application. + * You must first create a Run/Debug Configuration: + * Under the Argument tab, in Program Arguments you must set the -i or --input command line argument. + * You should also direct the output to a file using -o or --output. (default is Console) + * See the init() method in this file for other useful arguments. + * Example for a Windows machine: + * -i testsets/conformance/xacml3.0-ct-v.0.4 + * -o \Users\yourLogin\Downloads\conformance.txt + * You must also set the VM arguments: + * -Dxacml.properties=testsets/conformance/xacml.properties . + * -Dlog4j.configuration=.\logging.properties + * + * @version $Revision: 1.2 $ + */ +public class Conformance { + private ConformanceScopeResolver scopeResolver; + private ConformanceTestEngine testEngine; + private ConformanceTestSet testSet = new ConformanceTestSet(); + private File outputFile; + private PrintWriter outputFileWriter; + + private List testNamesToRun = new ArrayList(); + + private boolean verbose; + private boolean failuresOnly; + private boolean strict; + private boolean stopOnFirstError; + + private int testsRun; + private int decisionsMatch; + private int statusCodesMatch; + private int attributesMatch; + private int policyIdsMatch; + private int policySetIdsMatch; + private int associatedAdviceMatch; + private int obligationsMatch; + private int unknownFunctions; + + + + + protected synchronized ConformanceScopeResolver getScopeResolver() { + if (this.scopeResolver == null) { + this.scopeResolver = new ConformanceScopeResolver(); + + /* + * TODO: + * Add the known scopes for the 2.0 conformance test. This could be made more general by allowing loading + * from a properties file eventually. + */ + try { + URI ID_SCOPE_ROOT = new URI("urn:root"); + URI ID_SCOPE_CHILD1 = new URI("urn:root:child1"); + URI ID_SCOPE_CHILD2 = new URI("urn:root:child2"); + URI ID_SCOPE_C1D1 = new URI("urn:root:child1:descendant1"); + URI ID_SCOPE_C1D2 = new URI("urn:root:child1:descendant2"); + URI ID_SCOPE_C2D1 = new URI("urn:root:child2:descendant1"); + URI ID_SCOPE_C2D2 = new URI("urn:root:child2:descendant2"); + + this.scopeResolver.add(ID_SCOPE_ROOT, ID_SCOPE_CHILD1); + this.scopeResolver.add(ID_SCOPE_CHILD1, ID_SCOPE_C1D1); + this.scopeResolver.add(ID_SCOPE_CHILD1, ID_SCOPE_C1D2); + this.scopeResolver.add(ID_SCOPE_ROOT, ID_SCOPE_CHILD2); + this.scopeResolver.add(ID_SCOPE_CHILD2, ID_SCOPE_C2D1); + this.scopeResolver.add(ID_SCOPE_CHILD2, ID_SCOPE_C2D2); + } catch (Exception ex) { + ex.printStackTrace(System.err); + } + + } + return this.scopeResolver; + } + + private void close() throws IOException { + if (this.outputFileWriter != null) { + this.outputFileWriter.close(); + } + } + + private boolean init(String[] args) { + boolean lenientRequests = true; + boolean lenientPolicies = false; + // default is to not run any non-first-time iterations + int iterations = -1; + String testSetDirectoryNames = ""; + for (int i = 0 ; i < args.length ; ) { + + if (args[i].equals("-h") || args[i].equals("--help") || args[i].equals("-help")) { + printHelp(); + return false; + } + + + // where the XML Request/Response files are located + if (args[i].equals("-i") || args[i].equals("--input")) { + i++; + while (i < args.length && !args[i].startsWith("-")) { + testSetDirectoryNames += " " + args[i]; + try { + testSet.addConformanceTestSet(ConformanceTestSet.loadDirectory(new File(args[i]))); + } catch (Exception ex) { + ex.printStackTrace(System.err); + return false; + } + i++; + } + + // File path name where output will be put - default is stdout == Console + } else if (args[i].equals("-o") || args[i].equals("--output")) { + if (i+1 < args.length) { + this.outputFile = new File(args[i+1]); + i += 2; + } else { + System.err.println("Missing argument to " + args[i] + " command line option"); + return false; + } + // A list of specific test names (e.g.: -t IIA001 IIA007 IIIE301) - default is to run all tests + } else if (args[i].equals("-t") || args[i].equals("--tests")) { + i++; + while (i < args.length && !args[i].startsWith("-")) { + testNamesToRun.add(args[i]); + i++; + } + if (testNamesToRun.size() == 0) { + System.err.println("Missing test names after -t or --tests argument"); + return false; + } + // Include full details in the response, both the expected reqsponse (from file) and the actual response + } else if (args[i].equals("-v") || args[i].equals("--verbose")) { + this.verbose = true; + i++; + // Report only failures (success is silent) + } else if (args[i].equals("-f") || args[i].equals("--failures")) { + this.failuresOnly = true; + i++; + // When set, the XML must not contain extra attibutes/elements. Default is "lenient" where unexpected entries are ignored + } else if (args[i].equals("-s") || args[i].equals("--strict")) { + this.strict = true; + i++; + // (self explanatory) + } else if (args[i].equals("--stop-on-error")) { + this.stopOnFirstError = true; + i++; + } else if (args[i].equals("--lenient")) { + lenientPolicies = true; + lenientRequests = true; + i++; + } else if (args[i].equals("--lenient-policies")) { + lenientPolicies = true; + i++; + } else if (args[i].equals("--lenient-requests")) { + lenientRequests = true; + i++; + } else if (args[i].equals("--strict-policies")) { + lenientPolicies = false; + i++; + } else if (args[i].equals("--strict-requests")) { + lenientRequests = false; + i++; + } else if (args[i].equals("--iterations")) { + // this is a count of how many ADDITIONAL times the decide() should be called. + // The first time decide() is called it takes a long time to set up, + // so to get an accurate number for how fast a single Request is handled we need to ignore the time for the first run + // and timings for 1 or more non-first-time calls to decide(). + if (i+1 < args.length) { + try { + iterations = Integer.parseInt(args[i+1]); + i += 2; + } catch (NumberFormatException ex) { + System.err.println("Invalid iteration count '" + args[i+1] + "'"); + return false; + } + } else { + System.err.println("Missing argument to " + args[i] + " command line option"); + return false; + } + if (iterations < 1) { + System.err.println("Cannot use --iterations " + iterations + ". Must use an integer greater than 0"); + return false; + } + } else { + System.err.println("Unknown command line option " + args[i]); + return false; + } + } + + this.testEngine = new ConformanceTestEngine(this.getScopeResolver(), lenientRequests, lenientPolicies, iterations); + + if (testSetDirectoryNames.length() == 0) { + System.err.println("No test set directory given (need -i or --iniput command line option)"); + return false; + } + if (testSet.getListConformanceTests().size() == 0) { + System.err.println("No tests in given directories: " + testSetDirectoryNames); + } + + if (testNamesToRun.size() > 0) { + String s = ""; + for (String name : testNamesToRun) { + s += ", " + name; + } + System.out.println("Tests limited to: " + s.substring(1)); + } + + if (this.outputFile == null) { + this.outputFileWriter = new PrintWriter(System.out); + } else { + try { + this.outputFileWriter = new PrintWriter(new FileOutputStream(this.outputFile)); + } catch (IOException ex) { + System.err.println("Cannot open " + this.outputFile.getAbsolutePath() + " for writing."); + return false; + } + } + + return true; + } + + private void printHelp() { + System.out.println("usage: Conformance --input OPTIONS"); + System.out.println(""); + System.out.println(" -f, --failures Only include failed tests in the output. \n"+ + " Default is to include all test's results in the output file."); + System.out.println(""); + System.out.println(" -h, --help Prints help."); + + System.out.println(""); + System.out.println(" -i, --input Directory containing the XML Request/Response files. \n"+ + " This may be multiple space-separated directory paths. REQUIRED"); + + System.out.println(""); + System.out.println(" --iterations The number of times to run through the set of tests in the input directory."); + + System.out.println(""); + System.out.println(" --lenient Allow both Requests and Policies to have unexpected elements, no data in , etc. \n"+ + " Default is to not allow anything that is not explicitly listed in the XACML spec."); + + System.out.println(""); + System.out.println(" --lenient-policies Allow Policies to have unexpected elements, no data in , etc. \n" + + " Default is to not allow anything that is not explicitly listed in the XACML spec."); + + System.out.println(""); + System.out.println(" --lenient-requests Allow Requests to have unexpected elements, no data in , etc. \n" + + " Default is to not allow anything that is not explicitly listed in the XACML spec."); + + System.out.println(""); + System.out.println(" -o, --output Directory where the output results file will be put."); + + System.out.println(""); + System.out.println(" -s, --strict Check both the Decision and all other parts of the Response (Attributes, Obligations and Advice). \n "+ + " Default is to check just the Decision."); + + System.out.println(""); + System.out.println(" --stop-on-error Stop running conformance tests the first time one fails. Default is to continue through all tests."); + + System.out.println(""); + System.out.println(" --strict-policies Require Policies to have no unexpected elements, data in , etc. \n" + + " This is the default, but can be used to override Policies when option --lenient is used."); + + System.out.println(""); + System.out.println(" --strict-requests Require Requests to have no unexpected elements, data in , etc. \n" + + " This is the default, but can be used to override Requests when option --lenient is used."); + + System.out.println(""); + System.out.println(" -t, --tests A space-separated list of specific tests to be run. \n" + + " These are just the names of the tests as in 'IIA001 IIC178'. \n" + + " Default is to run all tests in the input directory."); + + System.out.println(""); + System.out.println(" -v, --verbose The entire expected and actual Response objects in the output. \n"+ + " Default is just a summary line."); + + } + + private boolean failed(ConformanceTestResult conformanceTestResult) { + ResponseMatchResult responseMatchResult = conformanceTestResult.getResponseMatchResult(); + if (responseMatchResult == null) { + return true; + } + if (!responseMatchResult.decisionsMatch() || !responseMatchResult.statusCodesMatch()) { + return true; + } else if (this.strict) { + if (!responseMatchResult.associatedAdviceMatches() || + !responseMatchResult.attributesMatch() || + !responseMatchResult.obligationsMatch() || + !responseMatchResult.policyIdentifiersMatch() || + !responseMatchResult.policySetIdentifiersMatch() + ) { + return true; + } + } + return false; + } + + private void dump(AttributeAssignment attributeAssignment) { + this.outputFileWriter.println("\t\t\t\tAttributeAssignment:"); + if (attributeAssignment.getCategory() != null) { + this.outputFileWriter.println("\t\t\t\t\tCategory: " + attributeAssignment.getCategory().stringValue()); + } + if (attributeAssignment.getAttributeId() != null) { + this.outputFileWriter.println("\t\t\t\t\tAttributeId: " + attributeAssignment.getAttributeId().stringValue()); + } + if (attributeAssignment.getDataTypeId() != null) { + this.outputFileWriter.println("\t\t\t\t\tDataType: " + attributeAssignment.getDataTypeId().stringValue()); + } + if (attributeAssignment.getIssuer() != null) { + this.outputFileWriter.println("\t\t\t\t\tIssuer: " + attributeAssignment.getIssuer()); + } + if (attributeAssignment.getAttributeValue() != null && attributeAssignment.getAttributeValue().getValue() != null) { + this.outputFileWriter.println("\t\t\t\t\tValue: " + attributeAssignment.getAttributeValue().getValue().toString()); + } + } + + private void dump(Attribute attribute) { + this.outputFileWriter.println("\t\t\t\t\tAttribute: " + (attribute.getAttributeId() == null ? "" : attribute.getAttributeId().stringValue())); + if (attribute.getIssuer() != null) { + this.outputFileWriter.println("\t\t\t\t\t\tIssuer: " + attribute.getIssuer()); + } + Iterator> iterAttributeValues = attribute.getValues().iterator(); + if (iterAttributeValues.hasNext()) { + this.outputFileWriter.println("\t\t\t\t\t\tValues: "); + while (iterAttributeValues.hasNext()) { + this.outputFileWriter.print("\t\t\t\t\t\t\t"); + AttributeValue attributeValue = iterAttributeValues.next(); + if (attributeValue.getDataTypeId() != null) { + this.outputFileWriter.print("DataType: " + attributeValue.getDataTypeId().stringValue() + " "); + } + if (attributeValue.getValue() != null) { + this.outputFileWriter.print("Value: " + attributeValue.getValue().toString()); + } + this.outputFileWriter.println(); + } + } + } + + private void dump(AttributeCategory attributeCategory) { + this.outputFileWriter.println("\t\t\tAttributeCategory: " + (attributeCategory.getCategory() == null ? "" : attributeCategory.getCategory().stringValue())); + Collection listAttributes = attributeCategory.getAttributes(); + if (listAttributes.size() > 0) { + this.outputFileWriter.println("\t\t\t\tAttributes:"); + for (Attribute attribute: listAttributes) { + this.dump(attribute); + } + } + } + + private void dump(Result result) { + this.outputFileWriter.println("\t\t======== Result =========="); + this.outputFileWriter.println("\t\tDecision: " + (result.getDecision() == null ? "null" : result.getDecision().name())); + if (result.getStatus() == null) { + this.outputFileWriter.println("\t\tStatus: null"); + } else { + this.outputFileWriter.println("\t\tStatus:"); + if (result.getStatus().getStatusCode() != null) { + this.outputFileWriter.println("\t\t\tStatusCode: " + result.getStatus().getStatusCode().toString()); + } + if (result.getStatus().getStatusMessage() != null) { + this.outputFileWriter.println("\t\t\tStatusMessage: " + result.getStatus().getStatusMessage()); + } + if (result.getStatus().getStatusDetail() != null) { + this.outputFileWriter.println("\t\t\tStatusDetail: " + result.getStatus().getStatusDetail().toString()); + } + } + Collection listAdvice = result.getAssociatedAdvice(); + if (listAdvice.size() > 0) { + this.outputFileWriter.println("\t\tAdvice:"); + for (Advice advice : listAdvice) { + if (advice.getId() != null) { + this.outputFileWriter.println("\t\t\tId: " + advice.getId().stringValue()); + } + Collection attributeAssignments = advice.getAttributeAssignments(); + if (attributeAssignments.size() > 0) { + this.outputFileWriter.println("\t\t\tAttributeAssignments:"); + for (AttributeAssignment attributeAssignment: attributeAssignments) { + this.dump(attributeAssignment); + } + } + } + } + Collection listObligations = result.getObligations(); + if (listObligations.size() > 0) { + for (Obligation obligation: listObligations) { + if (obligation.getId() != null) { + this.outputFileWriter.println("\t\t\tId: " + obligation.getId().stringValue()); + } + Collection attributeAssignments = obligation.getAttributeAssignments(); + if (attributeAssignments.size() > 0) { + this.outputFileWriter.println("\t\t\tAttributeAssignments:"); + for (AttributeAssignment attributeAssignment : attributeAssignments) { + this.dump(attributeAssignment); + } + } + } + } + Collection listAttributeCategories = result.getAttributes(); + if (listAttributeCategories.size() > 0) { + this.outputFileWriter.println("\t\tAttributes:"); + for (AttributeCategory attributeCategory : listAttributeCategories) { + this.dump(attributeCategory); + } + } + Collection listIdReferences; + if ((listIdReferences = result.getPolicyIdentifiers()).size() > 0) { + this.outputFileWriter.println("\t\tPolicyIds:"); + for (IdReference idReference : listIdReferences) { + this.outputFileWriter.println("\t\t\t" + idReference.toString()); + } + } + if ((listIdReferences = result.getPolicySetIdentifiers()).size() > 0) { + this.outputFileWriter.println("\t\tPolicySetIds:"); + for (IdReference idReference : listIdReferences) { + this.outputFileWriter.println("\t\t\t" + idReference.toString()); + } + } + } + + private void dump(String label, Response response) { + this.outputFileWriter.println("\t========== " + label + "=========="); + if (response == null) { + this.outputFileWriter.println("null"); + return; + } + + for (Result result : response.getResults()) { + this.dump(result); + } + } + + private void dump(ConformanceTestResult conformanceTestResult) { + + ResponseMatchResult responseMatchResult = conformanceTestResult.getResponseMatchResult(); + if (this.verbose) { + this.outputFileWriter.println("========== Test " + conformanceTestResult.getConformanceTest().getTestName() + " =========="); + this.dump("Expected Response", conformanceTestResult.getExpectedResponse()); + this.dump("Actual Response", conformanceTestResult.getActualResponse()); + if (responseMatchResult != null) { + this.outputFileWriter.println("\t========== Matching =========="); + this.outputFileWriter.println("\tDecisions Match? " + responseMatchResult.decisionsMatch()); + this.outputFileWriter.println("\tStatus Codes Match? " + responseMatchResult.statusCodesMatch()); + this.outputFileWriter.println("\tAttributes Match? " + responseMatchResult.attributesMatch()); + this.outputFileWriter.println("\tPolicyIds Match? " + responseMatchResult.policyIdentifiersMatch()); + this.outputFileWriter.println("\tPolicySetIds Match? " + responseMatchResult.policySetIdentifiersMatch()); + this.outputFileWriter.println("\tAssociated Advice Match? " + responseMatchResult.associatedAdviceMatches()); + this.outputFileWriter.println("\tObligations Match? " + responseMatchResult.obligationsMatch()); + this.outputFileWriter.println("========== End =========="); + } + } else { + String testName = conformanceTestResult.getConformanceTest().getTestName(); + if (responseMatchResult != null) { + Iterator iterResultMatches = responseMatchResult.getResultMatchResults(); + if (iterResultMatches == null || !iterResultMatches.hasNext()) { + this.outputFileWriter.println(testName); + } else { + while (iterResultMatches.hasNext()) { + ResultMatchResult resultMatchResult = iterResultMatches.next(); + this.outputFileWriter.printf("%s,%s,%s,%s,%s,%s,%s,%s,%d,%d\n", + testName, + resultMatchResult.decisionsMatch(), + resultMatchResult.statusCodesMatch(), + resultMatchResult.attributesMatch(), + resultMatchResult.policyIdentifiersMatch(), + resultMatchResult.policySetIdentifiersMatch(), + resultMatchResult.associatedAdviceMatches(), + resultMatchResult.obligationsMatch(), + conformanceTestResult.getFirstCallTime(), + conformanceTestResult.getAverageTotalLoopTime() + ); + } + } + } + } + this.outputFileWriter.flush(); + } + + private boolean run(ConformanceTest conformanceTest) throws Exception { + this.testsRun++; + ConformanceTestResult conformanceTestResult = this.testEngine.run(conformanceTest); + boolean bFailed = true; + if (conformanceTestResult != null) { + ResponseMatchResult responseMatchResult = conformanceTestResult.getResponseMatchResult(); + if (responseMatchResult != null) { + if (responseMatchResult.decisionsMatch()) { + this.decisionsMatch++; + this.statusCodesMatch += (responseMatchResult.statusCodesMatch() ? 1 : 0); + this.attributesMatch += (responseMatchResult.attributesMatch() ? 1 : 0); + this.policyIdsMatch += (responseMatchResult.policyIdentifiersMatch() ? 1 : 0); + this.policySetIdsMatch += (responseMatchResult.policySetIdentifiersMatch() ? 1 : 0); + this.associatedAdviceMatch += (responseMatchResult.associatedAdviceMatches() ? 1 : 0); + this.obligationsMatch += (responseMatchResult.obligationsMatch() ? 1 : 0); + } + this.unknownFunctions += (responseMatchResult.unknownFunction() ? 1 : 0); + bFailed = this.failed(conformanceTestResult); + if (bFailed || !this.failuresOnly) { + this.dump(conformanceTestResult); + } + } else if (conformanceTestResult.getError() != null) { + this.outputFileWriter.println(conformanceTestResult.getError()); + } + } + return (!bFailed || !this.stopOnFirstError); + } + + private void run() throws Exception { + long tStart = System.currentTimeMillis(); + + if (!this.verbose) { + this.outputFileWriter.println("Test,Decision,Status,Attributes,PolicyIds,PolicySetIds,Advice,Obligations"); + } + Iterator iterConformanceTests = this.testSet.getConformanceTests(); + boolean bContinue = true; + while (bContinue && iterConformanceTests.hasNext()) { +// bContinue = this.run(iterConformanceTests.next()); + ConformanceTest test = iterConformanceTests.next(); + if (testNamesToRun.size() > 0) { + if ( ! testNamesToRun.contains(test.getTestName())) { + continue; + } + } + bContinue = this.run(test); + } + + long tElapsed = System.currentTimeMillis() - tStart; + + if (this.verbose) { + this.outputFileWriter.println("Tests run = " + this.testsRun); + this.outputFileWriter.println("Decisions match = " + this.decisionsMatch); + this.outputFileWriter.println("Status Codes match = " + this.statusCodesMatch); + this.outputFileWriter.println("Attributes match = " + this.attributesMatch); + this.outputFileWriter.println("PolicyIds match = " + this.policyIdsMatch); + this.outputFileWriter.println("PolicySetIds match = " + this.policySetIdsMatch); + this.outputFileWriter.println("Associated Advice match = " + this.associatedAdviceMatch); + this.outputFileWriter.println("Obligations match = " + this.obligationsMatch); + this.outputFileWriter.println("Unknown functions = " + this.unknownFunctions); + } else { + this.outputFileWriter.printf("Total (%d),%d,%d,%d,%d,%d,%d,%d,%d\n", + this.testsRun, + this.decisionsMatch, + this.statusCodesMatch, + this.attributesMatch, + this.policyIdsMatch, + this.policySetIdsMatch, + this.associatedAdviceMatch, + this.obligationsMatch, + this.unknownFunctions); + } + + if (tElapsed > 0) { + long tHours = tElapsed / (60*60*1000); + tElapsed = tElapsed - tHours * 60 * 60 *1000; + long tMinutes = tElapsed / (60*1000); + tElapsed = tElapsed - tMinutes * 60 * 1000; + long tSeconds = tElapsed / 1000; + tElapsed = tElapsed - tSeconds * 1000; + + this.outputFileWriter.printf("Elapsed time = %02d:%02d:%02d.%03d\n", tHours, tMinutes, tSeconds, tElapsed); + this.outputFileWriter.printf("First decide time in nano-seconds %d\n", this.testEngine.getFirstDecideTime()); + this.outputFileWriter.printf("Total Multiple decide time in nano-seconds %d\n", this.testEngine.getDecideTimeMultiple()); + + this.outputFileWriter.printf("\nAverage First decide time in nano-seconds %d\n", this.testEngine.getAvgFirstDecideTime()); + this.outputFileWriter.printf("Average decide time after first call in nano-seconds %d\n", this.testEngine.getAvgDecideTimeMultiple()); + } + } + + public Conformance() { + } + + public static void main(String[] args) { + Conformance conformance = new Conformance(); + try { + if (conformance.init(args)) { + conformance.run(); + } + + } catch (Exception ex) { + ex.printStackTrace(System.err); + System.exit(1); + } finally { + try { + conformance.close(); + } catch (IOException ex) { + ex.printStackTrace(System.err); + } + } + System.exit(0); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformancePIPEngine.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformancePIPEngine.java new file mode 100644 index 000000000..2a3950189 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformancePIPEngine.java @@ -0,0 +1,242 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.Attribute; +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.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.pip.StdPIPResponse; +import com.att.research.xacml.std.pip.engines.ConfigurableEngine; +import com.att.research.xacml.util.FactoryException; + +/** + * ConformancePIPEngine implements the {@link com.att.research.xacml.api.pip.PIPFinder} interface to find attributes + * loaded from a text file containing the following fields: + * category-id,attribute-id,datatype-id,issuer,value + * + * @version $Revision: 1.1 $ + */ +public class ConformancePIPEngine implements ConfigurableEngine { + public static final String PROP_DESCRIPTION = ".description"; + public static final String PROP_FILE = ".file"; + + private static final Log logger = LogFactory.getLog(ConformancePIPEngine.class); + + private String name; + private String description; + private Map cache = new HashMap(); + private List listAttributes = new ArrayList(); + private DataTypeFactory dataTypeFactory; + + public ConformancePIPEngine() { + + } + + protected DataTypeFactory getDataTypeFactory() throws FactoryException { + if (this.dataTypeFactory == null) { + this.dataTypeFactory = DataTypeFactory.newInstance(); + } + return this.dataTypeFactory; + } + + protected static String generateKey(PIPRequest pipRequest) { + StringBuilder stringBuilder = new StringBuilder(pipRequest.getCategory().toString()); + stringBuilder.append('+'); + stringBuilder.append(pipRequest.getAttributeId().toString()); + stringBuilder.append('+'); + stringBuilder.append(pipRequest.getDataTypeId().toString()); + String issuer = pipRequest.getIssuer(); + if (issuer != null) { + stringBuilder.append('+'); + stringBuilder.append(issuer); + } + return stringBuilder.toString(); + } + + protected void store(String[] fields) throws FactoryException { + DataTypeFactory thisDataTypeFactory = this.getDataTypeFactory(); + Identifier identifierCategory = new IdentifierImpl(fields[0]); + Identifier identifierAttribute = new IdentifierImpl(fields[1]); + Identifier identifierDataType = new IdentifierImpl(fields[2]); + String issuer = (fields.length == 5 ? fields[3] : null); + String value = fields[fields.length - 1]; + + DataType dataType = thisDataTypeFactory.getDataType(identifierDataType); + if (dataType == null) { + logger.error("Unknown data type " + identifierDataType.stringValue()); + return; + } + + AttributeValue attributeValue = null; + try { + attributeValue = dataType.createAttributeValue(value); + } catch (DataTypeException ex) { + throw new FactoryException("DataTypeException creating AttributeValue", ex); + } + Attribute attribute = new StdMutableAttribute(identifierCategory, identifierAttribute, attributeValue, issuer, false); + this.listAttributes.add(attribute); + } + + public void loadAttributes(File fileAttributes) throws IOException, ParseException, FactoryException { + if (fileAttributes != null) { + if (!fileAttributes.exists()) { + throw new FileNotFoundException("Attributes file " + fileAttributes.getAbsolutePath() + " not found."); + } else if (!fileAttributes.canRead()) { + throw new IOException("Attributes file " + fileAttributes.getAbsolutePath() + " is not readable."); + } + + BufferedReader bufferedReader = null; + try { + bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(fileAttributes))); + String line; + while ((line = bufferedReader.readLine()) != null) { + if (line.length() > 0) { + String[] fields = line.split("[|]",-1); + if (fields.length < 4) { + logger.warn("Not enough fields in record \"" + line + "\""); + continue; + } + this.store(fields); + + } + } + } finally { + if (bufferedReader != null) { + bufferedReader.close(); + } + } + } + } + + protected Attribute findAttribute(PIPRequest pipRequest) { + Attribute attributeResult = null; + Iterator iterAttributes = this.listAttributes.iterator(); + while ((attributeResult == null) && iterAttributes.hasNext()) { + Attribute attributeTest = iterAttributes.next(); + if (pipRequest.getCategory().equals(attributeTest.getCategory()) && + pipRequest.getAttributeId().equals(attributeTest.getAttributeId()) && + (pipRequest.getIssuer() == null || pipRequest.getIssuer().equals(attributeTest.getIssuer()))) { + attributeResult = attributeTest; + } + } + return attributeResult; + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { + String pipRequestKey = generateKey(pipRequest); + PIPResponse pipResponse = this.cache.get(pipRequestKey); + if (pipResponse != null) { + return pipResponse; + } + Attribute attributeMatch = this.findAttribute(pipRequest); + if (attributeMatch == null) { + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } + /* + * Iterate through the values and only return the ones that match the requested data type + */ + List> matchingValues = new ArrayList>(); + Iterator> iterAttributeValues = attributeMatch.getValues().iterator(); + while (iterAttributeValues.hasNext()) { + AttributeValue attributeValue = iterAttributeValues.next(); + if (pipRequest.getDataTypeId().equals(attributeValue.getDataTypeId())) { + matchingValues.add(attributeValue); + } + } + if (matchingValues.size() > 0) { + Attribute attributeResponse = new StdMutableAttribute(attributeMatch.getCategory(), attributeMatch.getAttributeId(), matchingValues, attributeMatch.getIssuer(), false); + pipResponse = new StdPIPResponse(attributeResponse); + this.cache.put(pipRequestKey, pipResponse); + } + return pipResponse; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getDescription() { + return this.description; + } + + @Override + public void configure(String id, Properties properties) throws PIPException { + this.name = id; + this.description = properties.getProperty(id + PROP_DESCRIPTION); + if (this.description == null) { + this.description = "PIPEngine for the Conformance tests that loads attributes from a CSV file"; + } + String pipFile = properties.getProperty(id + PROP_FILE); + if (pipFile != null) { + try { + this.loadAttributes(new File(pipFile)); + } catch (Exception ex) { + logger.error("Exception loading PIP file " + pipFile, ex); + throw new PIPException("Exception loading PIP file " + pipFile, ex); + } + } + } + + @Override + public Collection attributesRequired() { + return Collections.emptyList(); + } + + @Override + public Collection attributesProvided() { + // + // We could return everything in our list + // + return Collections.emptyList(); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceRepository.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceRepository.java new file mode 100644 index 000000000..4ef3416ad --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceRepository.java @@ -0,0 +1,127 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import com.att.research.xacml.util.StringUtils; +import com.att.research.xacml.util.XACMLProperties; +import com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory; + +/** + * ConformanceRepository represents one or more policies for a single policy test, which will include one or more root policies, and + * zero or more referenced policies. + * + * @version $Revision$ + */ +public class ConformanceRepository { + private List rootPolicies = new ArrayList(); + private List referencedPolicies = new ArrayList(); + + private void setXACMLProperty(String propertyName, List listFiles) { + Iterator iterFiles = listFiles.iterator(); + StringBuilder stringBuilderIdList = new StringBuilder(); + while (iterFiles.hasNext()) { + File file = iterFiles.next(); + if (stringBuilderIdList.length() > 0) { + stringBuilderIdList.append(','); + } + stringBuilderIdList.append(file.getName()); + + XACMLProperties.setProperty(file.getName() + StdPolicyFinderFactory.PROP_FILE, file.getAbsolutePath()); + } + XACMLProperties.setProperty(propertyName, stringBuilderIdList.toString()); + } + + public ConformanceRepository() { + } + + public void setXACMLProperties() { + if (this.rootPolicies.size() > 0) { + this.setXACMLProperty(XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies); + } + if (this.referencedPolicies.size() > 0) { + this.setXACMLProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, this.referencedPolicies); + } + } + + private void loadProperty(File fileDir, Properties properties, String propertyName, List listFiles) { + String fileNameList = properties.getProperty(propertyName); + if (fileNameList != null) { + String[] fileNameArray = fileNameList.split("[,]",0); + if (fileNameArray != null && fileNameArray.length > 0) { + for (String fileName : fileNameArray) { + File file = new File(fileDir, fileName); + if (file.exists() && file.canRead()) { + listFiles.add(file); + } + } + } + } + } + + public void load(File fileRepository) throws IOException { + Properties propertiesRepository = new Properties(); + try (InputStream is = new FileInputStream(fileRepository)) { + propertiesRepository.load(is); + } + this.loadProperty(fileRepository.getParentFile(), propertiesRepository, XACMLProperties.PROP_ROOTPOLICIES, this.rootPolicies); + this.loadProperty(fileRepository.getParentFile(), propertiesRepository, XACMLProperties.PROP_REFERENCEDPOLICIES, this.referencedPolicies); + } + + public void addRootPolicy(File filePolicy) { + this.rootPolicies.add(filePolicy); + } + + public boolean hasRootPolicy() { + return (this.rootPolicies.size() > 0); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("{"); + boolean needComma = false; + + if (this.rootPolicies != null && this.rootPolicies.size() > 0) { + stringBuilder.append("rootPolicies="); + stringBuilder.append(StringUtils.toString(this.rootPolicies.iterator())); + needComma = true; + } + if (this.referencedPolicies != null && this.referencedPolicies.size() > 0) { + if (needComma) { + stringBuilder.append(','); + } + stringBuilder.append("referencedPolicies="); + stringBuilder.append(StringUtils.toString(this.referencedPolicies.iterator())); + needComma = true; + } + stringBuilder.append('}'); + return stringBuilder.toString(); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceScopeResolver.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceScopeResolver.java new file mode 100644 index 000000000..5e2b3ed0f --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceScopeResolver.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.pdp.ScopeQualifier; +import com.att.research.xacml.api.pdp.ScopeResolver; +import com.att.research.xacml.api.pdp.ScopeResolverException; +import com.att.research.xacml.api.pdp.ScopeResolverResult; +import com.att.research.xacml.std.StdMutableAttribute; +import com.att.research.xacml.std.StdScopeResolverResult; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.std.datatypes.DataTypes; + +/** + * ConformanceScopeResolver implements {@link com.att.research.xacml.pdp.ScopeResolver} for the conformance tests + * using a fixed set of hierarchical resources defined in a map. + * + * @version $Revision$ + */ +public class ConformanceScopeResolver implements ScopeResolver { + private Log logger = LogFactory.getLog(ConformanceScopeResolver.class); + private Map> mapIdentifierToChildren = new HashMap>(); + + public ConformanceScopeResolver() { + } + + public void add(URI identifierRoot, URI identifierChild) { + List listChildrenRoot = this.mapIdentifierToChildren.get(identifierRoot); + if (listChildrenRoot == null) { + listChildrenRoot = new ArrayList(); + this.mapIdentifierToChildren.put(identifierRoot, listChildrenRoot); + } + listChildrenRoot.add(identifierChild); + } + + private void addChildren(Attribute attributeResourceId, URI urnResourceIdValue, boolean bDescendants, List listAttributes) { + List listChildren = this.mapIdentifierToChildren.get(urnResourceIdValue); + if (listChildren != null) { + for (URI uriChild : listChildren) { + AttributeValue attributeValueURI = null; + try { + attributeValueURI = DataTypes.DT_ANYURI.createAttributeValue(uriChild); + if (attributeValueURI != null) { + listAttributes.add(new StdMutableAttribute(attributeResourceId.getCategory(), attributeResourceId.getAttributeId(), attributeValueURI, attributeResourceId.getIssuer(), attributeResourceId.getIncludeInResults())); + } + } catch (Exception ex) { + this.logger.error("Exception converting URI to an AttributeValue"); + } + if (bDescendants) { + this.addChildren(attributeResourceId, uriChild, bDescendants, listAttributes); + } + } + } + } + + private void addChildren(Attribute attributeResourceId, boolean bDescendants, List listAttributes) { + /* + * Iterate over the values that are URNs + */ + Iterator> iterAttributeValueURNs = attributeResourceId.findValues(DataTypes.DT_ANYURI); + if (iterAttributeValueURNs != null) { + while (iterAttributeValueURNs.hasNext()) { + this.addChildren(attributeResourceId, iterAttributeValueURNs.next().getValue(), bDescendants, listAttributes); + } + } + } + + @Override + public ScopeResolverResult resolveScope(Attribute attributeResourceId, ScopeQualifier scopeQualifier) throws ScopeResolverException { + List listAttributes = new ArrayList(); + switch(scopeQualifier) { + case CHILDREN: + listAttributes.add(attributeResourceId); + this.addChildren(attributeResourceId, false, listAttributes); + break; + case DESCENDANTS: + listAttributes.add(attributeResourceId); + this.addChildren(attributeResourceId, true, listAttributes); + break; + case IMMEDIATE: + listAttributes.add(attributeResourceId); + break; + default: + this.logger.error("Unknown ScopeQualifier: " + scopeQualifier.name()); + return new StdScopeResolverResult(new StdStatus(StdStatusCode.STATUS_CODE_SYNTAX_ERROR, "Unknown ScopeQualifier " + scopeQualifier.name())); + } + return new StdScopeResolverResult(listAttributes); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTest.java new file mode 100644 index 000000000..297a9d0d6 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTest.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.io.File; + +/** + * ConformanceTest represents a collection of XACML files with a root Policy document, optional referenced Policy documents, a Request, and a Response. + * + * @version $Revision: 1.2 $ + */ +public class ConformanceTest { + private String testName; + private File request; + private File response; + private ConformanceRepository repository; + + public ConformanceTest(String name, ConformanceRepository conformanceRepository, File fileRequest, File fileResponse) { + this.testName = name; + this.request = fileRequest; + this.response = fileResponse; + this.repository = conformanceRepository; + } + + public ConformanceTest(String name) { + this.testName = name; + } + + public String getTestName() { + return this.testName; + } + public void setTestName(String s) { + this.testName = s; + } + public ConformanceRepository getRepository() { + if (this.repository == null) { + this.repository = new ConformanceRepository(); + } + return this.repository; + } + public File getRequest() { + return this.request; + } + public void setRequest(File f) { + this.request = f; + } + public File getResponse() { + return this.response; + } + public void setResponse(File f) { + this.response = f; + } + + public boolean isComplete() { + return this.getTestName() != null && this.getRepository() != null && this.getRepository().hasRootPolicy() && this.getRequest() != null && this.getResponse() != null; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + boolean needColon = false; + if (this.getTestName() != null) { + stringBuilder.append(this.getTestName()); + needColon = true; + } + if (this.getRepository() != null) { + + } + if (this.getRequest() != null) { + if (needColon) { + stringBuilder.append(':'); + } + stringBuilder.append(this.getRequest().getName()); + needColon = true; + } + if (this.getResponse() != null) { + if (needColon) { + stringBuilder.append(':'); + } + stringBuilder.append(this.getResponse().getName()); + needColon = true; + } + return stringBuilder.toString(); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestEngine.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestEngine.java new file mode 100644 index 000000000..c24b5473f --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestEngine.java @@ -0,0 +1,219 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.pdp.PDPEngine; +import com.att.research.xacml.api.pdp.PDPEngineFactory; +import com.att.research.xacml.api.pdp.ScopeResolver; +import com.att.research.xacml.std.dom.DOMProperties; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacml.std.dom.DOMResponse; +import com.att.research.xacml.util.FactoryException; + +/** + * ConformanceTestEngine handles the creation of the PDPEngine for a ConformanceTest instance. + * + * @version $Revision: 1.2 $ + */ +public class ConformanceTestEngine { + private Log logger = LogFactory.getLog(ConformanceTestEngine.class); + + private PDPEngineFactory pdpEngineFactory; + private ScopeResolver scopeResolver; + private boolean lenientRequests; + private boolean lenientPolicies; + private int iterations = 1; + + // total of all first calls to decide() + private long firstDecideTime; + private int numberOfFirstDecides = 0; + + // total of all non-first-calls to decide() + private long decideTimeMultiple; + + // total of average time each test case uses for a Request + // (sum of : for each test case, average of all non-first-call calls to decide() ) + private long avgDecideTimeMultiple = 0; + + protected PDPEngineFactory getPDPEngineFactory() throws FactoryException { + if (this.pdpEngineFactory == null) { + this.pdpEngineFactory = PDPEngineFactory.newInstance(); + this.pdpEngineFactory.setScopeResolver(this.scopeResolver); + } + return this.pdpEngineFactory; + } + + public ConformanceTestEngine(ScopeResolver scopeResolverIn, boolean lenientRequestsIn, boolean lenientPoliciesIn, int iterationsIn) { + this.scopeResolver = scopeResolverIn; + this.lenientRequests = lenientRequestsIn; + this.lenientPolicies = lenientPoliciesIn; + this.iterations = iterationsIn; + } + + public ConformanceTestResult run(ConformanceTest conformanceTest) { + if (conformanceTest.getRequest() == null || conformanceTest.getResponse() == null || conformanceTest.getRepository() == null) { + logger.error("Incomplete Conformance Test: " + conformanceTest.getTestName()); + } + PDPEngineFactory thisPDPEngineFactory = null; + try { + thisPDPEngineFactory = this.getPDPEngineFactory(); + } catch (FactoryException ex) { + return new ConformanceTestResult(conformanceTest, ex); + } + + ConformanceTestResult conformanceTestResult = new ConformanceTestResult(conformanceTest, iterations); + + /* + * Load the request + */ + Request request = null; + boolean isLenient = DOMProperties.isLenient(); + try { + DOMProperties.setLenient(this.lenientRequests); + try { + request = DOMRequest.load(conformanceTest.getRequest()); + conformanceTestResult.setRequest(request); + } catch (Exception ex) { + logger.error("Exception loading Request file " + conformanceTest.getRequest().getAbsolutePath(), ex); + conformanceTestResult.setError(ex); + return conformanceTestResult; + + } + + /* + * Load the expected response + */ + Response response = null; + try { + response = DOMResponse.load(conformanceTest.getResponse()); + conformanceTestResult.setExpectedResponse(response); + } catch (Exception ex) { + logger.error("Exception loading Response file " + conformanceTest.getResponse().getAbsolutePath(), ex); + conformanceTestResult.setError(ex); + return conformanceTestResult; + } + + /* + * Set up the configuration for the policy finder + */ + conformanceTest.getRepository().setXACMLProperties(); + DOMProperties.setLenient(this.lenientPolicies); + + /* + * Create the engine + */ + PDPEngine pdpEngine = null; + try { + // pdpEngine = thisPDPEngineFactory.newEngine(conformanceTest.getRootPolicy(), conformanceTest.getReferencedPolicies(), pipFinderEngine); + pdpEngine = thisPDPEngineFactory.newEngine(); + } catch (Exception ex) { + logger.error("Exception getting PDP engine instance", ex); + conformanceTestResult.setError(ex); + return conformanceTestResult; + } + if (pdpEngine == null) { + logger.error("Null PDP engine"); + conformanceTestResult.setError(new NullPointerException("Null engine")); + return conformanceTestResult; + } + + /* + * Run the request + */ + long startTime, endTime; + long curDecideTime = this.firstDecideTime; + try { + startTime = System.nanoTime(); + response = pdpEngine.decide(request); + endTime = System.nanoTime(); +//System.out.println(endTime - startTime); + // add to total + this.firstDecideTime += endTime - startTime; + this.numberOfFirstDecides++; + // remember just this test + conformanceTestResult.setFirstCallTime(endTime - startTime); + conformanceTestResult.setActualResponse(response); + } catch (Exception ex) { + logger.error("Exception in decide", ex); + conformanceTestResult.setError(ex); + return conformanceTestResult; + } + if (response == null) { + logger.error("Null Response"); + conformanceTestResult.setError(new NullPointerException("Null Response")); + return conformanceTestResult; + } + + long localLoopTime = 0; + try { + // if user requested non-first-call calls to decide() to get performance info, run them now. + // We can ignore the result since we are only interested in how long they take to process the Request. + for (int i = 0 ; i < this.iterations ; i++) { + startTime = System.nanoTime(); + pdpEngine.decide(request); + endTime = System.nanoTime(); +//System.out.println(endTime - startTime); + // add to the global total for all tests + this.decideTimeMultiple += (endTime - startTime); + // remember just this one test's info + localLoopTime += (endTime - startTime); + } + } catch (Exception ex) { + logger.error("Exception in iterated decide", ex); + return conformanceTestResult; + } + + // add to total average for non-first-call times for all test cases + avgDecideTimeMultiple += (localLoopTime / iterations); +//System.out.println("localLoop="+localLoopTime + " it="+iterations + " avg=" + (localLoopTime / iterations) ); + // remember average time for just this test + conformanceTestResult.setAverageTotalLoopTime(localLoopTime/iterations); + + long elapsedDecideTime = this.firstDecideTime - curDecideTime; + logger.info("Decide Time: " + elapsedDecideTime + "ns"); + + return conformanceTestResult; + } finally { + DOMProperties.setLenient(isLenient); + } + } + + public long getFirstDecideTime() { + return this.firstDecideTime; + } + + public long getDecideTimeMultiple() { + return this.decideTimeMultiple; + } + + + public long getAvgFirstDecideTime() { + return this.firstDecideTime / numberOfFirstDecides; + } + public long getAvgDecideTimeMultiple() { + return this.avgDecideTimeMultiple / numberOfFirstDecides; + } +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestResult.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestResult.java new file mode 100644 index 000000000..feef1144d --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestResult.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.Response; + +/** + * ConformanceTestResult holds all of the objects for a single conformance test run. + * + * @version $Revision: 1.1 $ + */ +public class ConformanceTestResult { + private ConformanceTest conformanceTest; + private Request request; + private Response expectedResponse; + private Response actualResponse; + private ResponseMatchResult responseMatchResult; + private Exception error; + + // performance timings + private long firstCallTime; + private long averageTotalLoopTime; + + // how many non-first-call times the decide() was called + private int iterations; + + public ConformanceTestResult(ConformanceTest conformanceTestIn, int iterations) { + this.conformanceTest = conformanceTestIn; + this.iterations = iterations; + } + + public ConformanceTestResult(ConformanceTest conformanceTestIn, Exception errorIn) { + this.conformanceTest = conformanceTestIn; + this.error = errorIn; + } + + public int getIterations() { + return this.iterations; + } + + public ConformanceTest getConformanceTest() { + return this.conformanceTest; + } + public void setConformanceTest(ConformanceTest conformanceTestIn) { + this.conformanceTest = conformanceTestIn; + } + + public Request getRequest() { + return this.request; + } + public void setRequest(Request requestIn) { + this.request = requestIn; + } + + public Response getExpectedResponse() { + return this.expectedResponse; + } + public void setExpectedResponse(Response response) { + this.expectedResponse = response; + this.responseMatchResult = null; + } + + public Response getActualResponse() { + return this.actualResponse; + } + public void setActualResponse(Response response) { + this.actualResponse = response; + this.responseMatchResult = null; + } + + public ResponseMatchResult getResponseMatchResult() { + if (this.responseMatchResult == null && (this.actualResponse != null && this.expectedResponse != null)) { + this.computeResponseMatchResult(); + } + return this.responseMatchResult; + } + public void computeResponseMatchResult() { + if (this.expectedResponse != null && this.actualResponse != null) { + this.responseMatchResult = ResponseMatchResult.newInstance(this.expectedResponse, this.actualResponse); + } + } + public Exception getError() { + return this.error; + } + public void setError(Exception ex) { + this.error = ex; + } + + public long getFirstCallTime() { + return firstCallTime; + } + public void setFirstCallTime(long t) { + firstCallTime = t; + } + public long getAverageTotalLoopTime(){ + return averageTotalLoopTime; + } + public void setAverageTotalLoopTime(long t) { + averageTotalLoopTime = t; + } + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestSet.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestSet.java new file mode 100644 index 000000000..b9ae0873f --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ConformanceTestSet.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * ConformanceTestSet represents a collection of ConformanceTests ordered by the test name. It has methods for + * scanning a directory to generate an ordered set. + * + * @version $Revision: 1.1 $ + */ +public class ConformanceTestSet { + private static final Log logger = LogFactory.getLog(ConformanceTestSet.class); + private List listConformanceTests = new ArrayList(); + + protected List getListConformanceTests() { + return this.listConformanceTests; + } + + protected ConformanceTestSet() { + + } + + private static String getTestName(String fileName, int itemPos) { + return (itemPos == 0 ? "NULL" : fileName.substring(0, itemPos)); + } + + private static String getTestName(File file) { + String fileName = file.getName(); + int itemPos = fileName.indexOf("Policy"); + if (itemPos >= 0) { + return getTestName(fileName, itemPos); + } else if ((itemPos = fileName.indexOf("Request")) >= 0) { + return getTestName(fileName, itemPos); + } else if ((itemPos = fileName.indexOf("Response")) >= 0) { + return getTestName(fileName, itemPos); + } else if ((itemPos = fileName.indexOf("Repository")) >= 0) { + return getTestName(fileName, itemPos); + } else { + return null; + } + } + + public static ConformanceTestSet loadDirectory(File fileDir) throws IOException { + final Map mapConformanceTests = new HashMap(); + + Files.walkFileTree(fileDir.toPath(), new FileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + logger.info("Scanning directory " + dir.getFileName()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + File fileVisited = file.toFile(); + String fileName = fileVisited.getName(); + if (fileName.endsWith(".xml") || fileName.endsWith(".properties")) { + String testName = getTestName(fileVisited); + if (testName != null) { + ConformanceTest conformanceTest = mapConformanceTests.get(testName); + if (conformanceTest == null) { + logger.info("Added test " + testName); + conformanceTest = new ConformanceTest(testName); + mapConformanceTests.put(testName, conformanceTest); + } + if (fileName.endsWith("Policy.xml")) { + conformanceTest.getRepository().addRootPolicy(fileVisited); + } else if (fileName.endsWith("Repository.properties")) { + conformanceTest.getRepository().load(fileVisited); + } else if (fileName.endsWith("Request.xml")) { + conformanceTest.setRequest(fileVisited); + } else if (fileName.endsWith("Response.xml")) { + conformanceTest.setResponse(fileVisited); + } + } + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + logger.warn("Skipped " + file.getFileName()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + }); + + /* + * Sort the keyset and pull out the tests that have the required components + */ + List listTestNames = new ArrayList(); + listTestNames.addAll(mapConformanceTests.keySet()); + Collections.sort(listTestNames); + + ConformanceTestSet conformanceTestSet = new ConformanceTestSet(); + Iterator iterTestNames = listTestNames.iterator(); + while (iterTestNames.hasNext()) { + ConformanceTest conformanceTest = mapConformanceTests.get(iterTestNames.next()); + if (conformanceTest.isComplete()) { + conformanceTestSet.addConformanceTest(conformanceTest); + logger.debug("Added conformance test " + conformanceTest.getTestName()); + } else { + logger.warn("Incomplete conformance test " + conformanceTest.getTestName()); + } + } + + return conformanceTestSet; + + } + + public Iterator getConformanceTests() { + return this.listConformanceTests.iterator(); + } + + public void addConformanceTest(ConformanceTest conformanceTest) { + this.listConformanceTests.add(conformanceTest); + } + + public void addConformanceTestSet(ConformanceTestSet conformanceTestSet) { + this.listConformanceTests.addAll(conformanceTestSet.getListConformanceTests()); + } + + public static void main(String[] args) { + for (String dir : args) { + try { + ConformanceTestSet conformanceTestSet = ConformanceTestSet.loadDirectory(new File(dir)); + Iterator iterConformanceTests = conformanceTestSet.getConformanceTests(); + if (iterConformanceTests == null) { + System.out.println("No tests found in " + dir); + } else { + System.out.println("Tests found in " + dir); + while (iterConformanceTests.hasNext()) { + System.out.println(iterConformanceTests.next().toString()); + } + } + } catch (Exception ex) { + ex.printStackTrace(System.err); + } + } + } +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResponseMatchResult.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResponseMatchResult.java new file mode 100644 index 000000000..31e6da415 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResponseMatchResult.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; + +/** + * ResponseMatchResult provides information about how a {@link com.att.research.xacml.api.Response} object matches + * another Response object. + * + * @version $Revision: 1.1 $ + */ +public class ResponseMatchResult { + private List resultMatchResults = new ArrayList(); + + private boolean bAssociatedAdviceMatches = true; + private boolean bAttributesMatch = true; + private boolean bDecisionsMatch = true; + private boolean bStatusCodesMatch = true; + private boolean bObligationsMatch = true; + private boolean bPolicyIdentifiersMatch = true; + private boolean bPolicySetIdentifiersMatch = true; + private boolean bNumResultsMatch = true; + private boolean bUnknownFunction; + + protected void addResultMatchResult(ResultMatchResult resultMatchResult) { + this.resultMatchResults.add(resultMatchResult); + this.bAssociatedAdviceMatches = resultMatchResult.associatedAdviceMatches() && this.bAssociatedAdviceMatches; + this.bAttributesMatch = resultMatchResult.attributesMatch() && this.bAttributesMatch; + this.bDecisionsMatch = resultMatchResult.decisionsMatch() && this.bDecisionsMatch; + this.bStatusCodesMatch = resultMatchResult.statusCodesMatch() && this.bStatusCodesMatch; + this.bObligationsMatch = resultMatchResult.obligationsMatch() && this.bObligationsMatch; + this.bPolicyIdentifiersMatch = resultMatchResult.policyIdentifiersMatch() && this.bPolicyIdentifiersMatch; + this.bPolicySetIdentifiersMatch = resultMatchResult.policySetIdentifiersMatch() && this.bPolicySetIdentifiersMatch; + this.bUnknownFunction = resultMatchResult.unknownFunction() || this.bUnknownFunction; + } + + protected void setNumResultsMatch(boolean b) { + this.bNumResultsMatch = b; + } + + public ResponseMatchResult() { + } + + public static ResponseMatchResult newInstance(Response response1, Response response2) { + ResponseMatchResult responseMatchResult = new ResponseMatchResult(); + + Collection listResultsResponse1 = response1.getResults(); + Collection listResultsResponse2 = response2.getResults(); + if (listResultsResponse1.size() == 1 && listResultsResponse2.size() == 1) { + /* + * Just add a single ResultMatchResult comparing the results in the two responses + */ + responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(listResultsResponse1.iterator().next(), listResultsResponse2.iterator().next())); + } else { + /* + * Iterate over all of the results in the two responses and match them + */ + Iterator iterResponse1Results = listResultsResponse1.iterator(); + Iterator iterResponse2Results = listResultsResponse2.iterator(); + while ((iterResponse1Results != null && iterResponse1Results.hasNext()) || (iterResponse2Results != null && iterResponse2Results.hasNext())) { + Result result1 = (iterResponse1Results != null && iterResponse1Results.hasNext() ? iterResponse1Results.next() : null); + Result result2 = (iterResponse2Results != null && iterResponse2Results.hasNext() ? iterResponse2Results.next() : null); + if ((result1 == null || result2 == null) && responseMatchResult.numResultsMatch()) { + responseMatchResult.setNumResultsMatch(false); + } + responseMatchResult.addResultMatchResult(ResultMatchResult.newInstance(result1, result2)); + } + } + return responseMatchResult; + } + + public Iterator getResultMatchResults() { + return this.resultMatchResults.iterator(); + } + + public boolean numResultsMatch() { + return this.bNumResultsMatch; + } + + public boolean associatedAdviceMatches() { + return this.bAssociatedAdviceMatches; + } + + public boolean attributesMatch() { + return this.bAttributesMatch; + } + + public boolean decisionsMatch() { + return this.bDecisionsMatch; + } + + public boolean obligationsMatch() { + return this.bObligationsMatch; + } + + public boolean policyIdentifiersMatch() { + return this.bPolicyIdentifiersMatch; + } + + public boolean policySetIdentifiersMatch() { + return this.bPolicySetIdentifiersMatch; + } + + public boolean statusCodesMatch() { + return this.bStatusCodesMatch; + } + + public boolean unknownFunction() { + return this.bUnknownFunction; + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResultMatchResult.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResultMatchResult.java new file mode 100644 index 000000000..3da7e1a83 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/conformance/ResultMatchResult.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * 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.pdp.test.conformance; + +import com.att.research.xacml.api.Result; +import com.att.research.xacml.std.StdStatusCode; +import com.att.research.xacml.util.ListUtil; + +/** + * ResultMatchResult provides information about how well a {@link com.att.research.xacml.api.Result} object matches + * another Result object. + * + * @version $Revision: 1.1 $ + */ +public class ResultMatchResult { + private boolean bAssociatedAdviceMatches = true; + private boolean bAttributesMatch = true; + private boolean bDecisionsMatch = true; + private boolean bObligationsMatch = true; + private boolean bPolicyIdentifiersMatch = true; + private boolean bPolicySetIdentifiersMatch = true; + private boolean bStatusCodesMatch = true; + private boolean bUnknownFunction = false; + + protected void setAssociatedAdviceMatches(boolean b) { + this.bAssociatedAdviceMatches = b; + } + protected void setAttributesMatch(boolean b) { + this.bAttributesMatch = b; + } + protected void setDecisionsMatch(boolean b) { + this.bDecisionsMatch = b; + } + protected void setObligationsMatch(boolean b) { + this.bObligationsMatch = b; + } + protected void setPolicyIdentifiersMatch(boolean b) { + this.bPolicyIdentifiersMatch = b; + } + protected void setPolicySetIdentifiersMatch(boolean b) { + this.bPolicySetIdentifiersMatch = b; + } + protected void setStatusCodesMatch(boolean b) { + this.bStatusCodesMatch = b; + } + protected void setUnknownFunction(boolean b) { + this.bUnknownFunction = b; + } + + public ResultMatchResult() { + } + + public static ResultMatchResult newInstance(Result result1, Result result2) { + ResultMatchResult resultMatchResult = new ResultMatchResult(); + if (result2 != null && result2.getStatus() != null && + result2.getStatus().getStatusCode().equals(StdStatusCode.STATUS_CODE_PROCESSING_ERROR) && + result2.getStatus().getStatusMessage() != null && + result2.getStatus().getStatusMessage().contains("Unknown Function") + ) { + resultMatchResult.setUnknownFunction(true); + } + if (result1 == null || result2 == null) { + resultMatchResult.setAssociatedAdviceMatches(false); + resultMatchResult.setAttributesMatch(false); + resultMatchResult.setDecisionsMatch(false); + resultMatchResult.setObligationsMatch(false); + resultMatchResult.setPolicyIdentifiersMatch(false); + resultMatchResult.setPolicySetIdentifiersMatch(false); + resultMatchResult.setStatusCodesMatch(false); + } else { + resultMatchResult.setAssociatedAdviceMatches(ListUtil.equalsAllowNulls(result1.getAssociatedAdvice(), result2.getAssociatedAdvice())); + resultMatchResult.setAttributesMatch(ListUtil.equalsAllowNulls(result1.getAttributes(), result2.getAttributes())); + resultMatchResult.setDecisionsMatch(result1.getDecision() == result2.getDecision()); + resultMatchResult.setObligationsMatch(ListUtil.equalsAllowNulls(result1.getObligations(), result2.getObligations())); + resultMatchResult.setPolicyIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicyIdentifiers(), result2.getPolicyIdentifiers())); + resultMatchResult.setPolicySetIdentifiersMatch(ListUtil.equalsAllowNulls(result1.getPolicySetIdentifiers(), result2.getPolicySetIdentifiers())); + if (result1.getStatus() == null || result1.getStatus().getStatusCode() == null || result2.getStatus() == null || result2.getStatus().getStatusCode() == null) { + resultMatchResult.setStatusCodesMatch(false); + } else { + resultMatchResult.setStatusCodesMatch(result1.getStatus().getStatusCode().equals(result2.getStatus().getStatusCode())); + } + } + return resultMatchResult; + } + + public boolean associatedAdviceMatches() { + return this.bAssociatedAdviceMatches; + } + + public boolean attributesMatch() { + return this.bAttributesMatch; + } + + public boolean decisionsMatch() { + return this.bDecisionsMatch; + } + + public boolean obligationsMatch() { + return this.bObligationsMatch; + } + + public boolean policyIdentifiersMatch() { + return this.bPolicyIdentifiersMatch; + } + + public boolean policySetIdentifiersMatch() { + return this.bPolicySetIdentifiersMatch; + } + + public boolean statusCodesMatch() { + return this.bStatusCodesMatch; + } + + public boolean unknownFunction() { + return this.bUnknownFunction; + } + +} -- cgit 1.2.3-korg