| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| * |
| */ |
| |
| /* |
| * AT&T - PROPRIETARY |
| * THIS FILE CONTAINS PROPRIETARY INFORMATION OF |
| * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN |
| * ACCORDANCE WITH APPLICABLE AGREEMENTS. |
| * |
| * Copyright (c) 2014 AT&T Knowledge Ventures |
| * Unpublished and Not for Publication |
| * All Rights Reserved |
| */ |
| package org.apache.openaz.xacml.pdp.test.policy; |
| |
| 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.DefaultParser; |
| 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 org.apache.openaz.xacml.api.AttributeValue; |
| import org.apache.openaz.xacml.api.DataType; |
| import org.apache.openaz.xacml.api.DataTypeException; |
| import org.apache.openaz.xacml.api.DataTypeFactory; |
| import org.apache.openaz.xacml.api.Identifier; |
| import org.apache.openaz.xacml.api.XACML3; |
| import org.apache.openaz.xacml.pdp.test.TestBase; |
| import org.apache.openaz.xacml.std.IdentifierImpl; |
| import org.apache.openaz.xacml.util.FactoryException; |
| import org.apache.openaz.xacml.util.XACMLObjectCopy; |
| import org.apache.openaz.xacml.util.XACMLPolicyAggregator; |
| import org.apache.openaz.xacml.util.XACMLPolicyScanner; |
| import org.apache.openaz.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 org.apache.commons.cli.ParseException |
| * @throws java.net.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 org.apache.openaz.xacml.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 = new DefaultParser().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 org.apache.openaz.xacml.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)) { |
| // |
| // 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; } |
| */ |
| |
| } |