aboutsummaryrefslogtreecommitdiffstats
path: root/ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java
diff options
context:
space:
mode:
Diffstat (limited to 'ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java')
-rw-r--r--ECOMP-XACML/src/test/java/org/openecomp/policy/xacml/test/TestPolicy.java792
1 files changed, 792 insertions, 0 deletions
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;
+ }
+
+ */
+
+}
+