Commit 6075e6e2 authored by cdanger's avatar cdanger

Merge branch 'release/12.0.0'

parents 101c3ecb 4e2a4e99
......@@ -7,6 +7,18 @@ All notable changes to this project are documented in this file following the [K
- Issues reported on [OW2's GitLab](https://gitlab.ow2.org/authzforce/core/issues) are referenced in the form of `[GL-N]`, where N is the issue number.
## 12.0.0
### Changed
- Dependency authzforce-ce-core-pdp-api: version 13.0.0 -> 14.0.0; changes APIs for PDP AttributeProvider and DecisionCache extensions:
- Interface method DecisionCache.Factory#getInstance(...): added EnvironmentProperties parameter to allow passing environment properties to DecisionCache implementations
- Interface method AttributeProvider#get(...): replaced parameter type BagDatatype with Datatype to simplify AttributeProviders' code
### Added
- Base implementations of a few interfaces to help implementing unit tests for PDP extensions:
- BasePrimaryPolicyMetadata, implements PrimaryPolicyMetadata
- IndividualDecisionRequestContext, implements EvaluationContext
## 11.0.1
### Fixed
- [GL-6]: IllegalArgumentException when applying XACML 'map' function to substring with string bag as first arg
......
......@@ -231,18 +231,18 @@ If you are using the Java API with extensions configured by XML (Policy Provider
## Support
If you are experiencing any issue with this project, please report it on the [OW2 Issue Tracker](https://jira.ow2.org/browse/AUTHZFORCE/).
You should use [AuthzForce users' mailing list](https://mail.ow2.org/wws/info/authzforce-users) as first contact for any communication about AuthzForce: question, feature request, notification, potential issue (unconfirmed), etc.
If you are experiencing any bug with this project and you indeed confirm this is not an issue with your environment (contact the users mailing list first if you are unsure), please report it on the [OW2 Issue Tracker](https://jira.ow2.org/browse/AUTHZFORCE/).
Please include as much information as possible; the more we know, the better the chance of a quicker resolution:
* Software version
* Platform (OS and JRE)
* Stack traces generally really help! If in doubt include the whole thing; often exceptions get wrapped in other exceptions and the exception right near the bottom explains the actual error, not the first few lines at the top. It's very easy for us to skim-read past unnecessary parts of a stack trace.
* Stack traces generally really help! If in doubt, include the whole thing; often exceptions get wrapped in other exceptions and the exception right near the bottom explains the actual error, not the first few lines at the top. It's very easy for us to skim-read past unnecessary parts of a stack trace.
* Log output can be useful too; sometimes enabling DEBUG logging can help;
* Your code & configuration files are often useful.
If you wish to contact the developers for other reasons, use [AuthzForce contact mailing list](http://scr.im/azteam).
## Vulnerability reporting
## Security - Vulnerability reporting
If you want to report a vulnerability, you must do so on the [OW2 Issue Tracker](https://jira.ow2.org/browse/AUTHZFORCE/) with *Security Level* set to **Private**. Then, if the AuthzForce team can confirm it, they will change it to **Public** and set a fix version.
## Contributing
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>11.0.1</version>
<version>12.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-cli</artifactId>
......@@ -30,12 +30,12 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>11.0.1</version>
<version>12.0.0</version>
</dependency>
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-io-xacml-json</artifactId>
<version>11.0.1</version>
<version>12.0.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
......@@ -46,7 +46,7 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-testutils</artifactId>
<version>11.0.1</version>
<version>12.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
......
org.ow2.authzforce.core.pdp.io.xacml.json.SingleDecisionXacmlJsonRequestPreprocessor$LaxVariantFactory
org.ow2.authzforce.core.pdp.io.xacml.json.SingleDecisionXacmlJsonRequestPreprocessor$StrictVariantFactory
org.ow2.authzforce.core.pdp.io.xacml.json.BaseXacmlJsonResultPostprocessor$Factory
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>11.0.1</version>
<version>12.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
......
......@@ -22,22 +22,16 @@ import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import javax.xml.datatype.XMLGregorianCalendar;
import net.sf.saxon.s9api.XdmNode;
import org.ow2.authzforce.core.pdp.api.AttributeFqn;
import org.ow2.authzforce.core.pdp.api.AttributeFqns;
import org.ow2.authzforce.core.pdp.api.AttributeSelectorId;
import org.ow2.authzforce.core.pdp.api.AttributeSources;
import org.ow2.authzforce.core.pdp.api.CloseablePdpEngine;
import org.ow2.authzforce.core.pdp.api.DecisionCache;
......@@ -48,24 +42,16 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.HashCollections;
import org.ow2.authzforce.core.pdp.api.ImmutableDecisionRequest;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.UpdatableCollections;
import org.ow2.authzforce.core.pdp.api.UpdatableMap;
import org.ow2.authzforce.core.pdp.api.expression.AttributeSelectorExpression;
import org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory;
import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import org.ow2.authzforce.core.pdp.api.policy.RootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.value.AttributeBag;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.Bag;
import org.ow2.authzforce.core.pdp.api.value.BagDatatype;
import org.ow2.authzforce.core.pdp.api.value.Bags;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
import org.ow2.authzforce.core.pdp.api.value.DateTimeValue;
import org.ow2.authzforce.core.pdp.api.value.DateValue;
import org.ow2.authzforce.core.pdp.api.value.StandardDatatypes;
import org.ow2.authzforce.core.pdp.api.value.TimeValue;
import org.ow2.authzforce.core.pdp.api.value.Value;
import org.ow2.authzforce.core.pdp.api.value.XPathValue;
import org.ow2.authzforce.core.pdp.impl.policy.RootPolicyEvaluator;
import org.ow2.authzforce.core.pdp.impl.policy.RootPolicyEvaluators;
import org.ow2.authzforce.core.xmlns.pdp.StandardEnvironmentAttributeSource;
......@@ -74,8 +60,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.MutableClassToInstanceMap;
import net.sf.saxon.s9api.XdmNode;
/**
* This is the core XACML PDP engine implementation.
......@@ -116,10 +102,9 @@ public final class BasePdpEngine implements CloseablePdpEngine
*/
// current datetime in default timezone
final DateTimeValue currentDateTimeValue = new DateTimeValue(new GregorianCalendar());
return HashCollections.<AttributeFqn, AttributeBag<?>> newImmutableMap(
return HashCollections.<AttributeFqn, AttributeBag<?>>newImmutableMap(
// current date-time
StandardEnvironmentAttribute.CURRENT_DATETIME.getFQN(),
Bags.singletonAttributeBag(StandardDatatypes.DATETIME, currentDateTimeValue, AttributeSources.PDP),
StandardEnvironmentAttribute.CURRENT_DATETIME.getFQN(), Bags.singletonAttributeBag(StandardDatatypes.DATETIME, currentDateTimeValue, AttributeSources.PDP),
// current date
StandardEnvironmentAttribute.CURRENT_DATE.getFQN(),
Bags.singletonAttributeBag(StandardDatatypes.DATE, DateValue.getInstance((XMLGregorianCalendar) currentDateTimeValue.getUnderlyingValue().clone()), AttributeSources.PDP),
......@@ -188,284 +173,6 @@ public final class BasePdpEngine implements CloseablePdpEngine
}
}
/**
* An {@link EvaluationContext} associated to an XACML Individual Decision Request, i.e. for evaluation to a single authorization decision Result (see Multiple Decision Profile spec for more
* information on Individual Decision Request as opposed to Multiple Decision Request).
*
* @version $Id: $
*/
private static final class IndividualDecisionRequestContext implements EvaluationContext
{
/**
* Logger used for all classes
*/
private static final Logger LOGGER = LoggerFactory.getLogger(IndividualDecisionRequestContext.class);
private final Map<AttributeFqn, AttributeBag<?>> namedAttributes;
/*
* Corresponds to Attributes/Content (by attribute category) marshalled to XPath data model for XPath evaluation: AttributeSelector evaluation, XPath-based functions, etc. This may be empty if
* no Content in Request or no feature requiring XPath evaluation against Content is supported/enabled.
*/
// Not null
private final Map<String, XdmNode> extraContentsByAttributeCategory;
/*
* AttributeSelector evaluation results. Not null
*/
private final UpdatableMap<AttributeSelectorId, Bag<?>> attributeSelectorResults;
private final Map<String, Value> varValsById = HashCollections.newMutableMap();
private final Map<String, Object> mutableProperties = HashCollections.newMutableMap();
private final boolean returnApplicablePolicyIdList;
private final ClassToInstanceMap<Listener> listeners = MutableClassToInstanceMap.create();
/**
* Constructs a new <code>IndividualDecisionRequestContext</code> based on the given request attributes and extra contents with support for XPath evaluation against Content element in
* Attributes
*
* @param namedAttributeMap
* updatable named attribute map (attribute key and value pairs) from the original Request; null iff none. An attribute key is a global ID based on attribute category,issuer,id. An
* attribute value is a bag of primitive values.
* @param extraContentsByCategory
* extra contents by attribute category (equivalent to XACML Attributes/Content elements); null iff no Content in the attribute category.
* @param returnApplicablePolicyIdList
* true iff list of IDs of policies matched during evaluation must be returned
*/
public IndividualDecisionRequestContext(final Map<AttributeFqn, AttributeBag<?>> namedAttributeMap, final Map<String, XdmNode> extraContentsByCategory,
final boolean returnApplicablePolicyIdList)
{
this.namedAttributes = namedAttributeMap == null ? HashCollections.<AttributeFqn, AttributeBag<?>> newUpdatableMap() : HashCollections
.<AttributeFqn, AttributeBag<?>> newUpdatableMap(namedAttributeMap);
this.returnApplicablePolicyIdList = returnApplicablePolicyIdList;
if (extraContentsByCategory == null)
{
this.extraContentsByAttributeCategory = Collections.emptyMap();
this.attributeSelectorResults = UpdatableCollections.emptyMap();
}
else
{
this.extraContentsByAttributeCategory = extraContentsByCategory;
this.attributeSelectorResults = UpdatableCollections.newUpdatableMap();
}
}
/** {@inheritDoc} */
@Override
public <AV extends AttributeValue> AttributeBag<AV> getNamedAttributeValue(final AttributeFqn attributeFqn, final BagDatatype<AV> attributeBagDatatype) throws IndeterminateEvaluationException
{
final AttributeBag<?> bagResult = namedAttributes.get(attributeFqn);
if (bagResult == null)
{
return null;
}
final Datatype<?> expectedElementDatatype = attributeBagDatatype.getElementType();
if (!bagResult.getElementDatatype().equals(expectedElementDatatype))
{
throw new IndeterminateEvaluationException(
"Datatype ("
+ bagResult.getElementDatatype()
+ ") of AttributeDesignator "
+ attributeFqn
+ " in context is different from expected/requested ("
+ expectedElementDatatype
+ "). May be caused by refering to the same Attribute Category/Id/Issuer with different Datatypes in different policy elements and/or attribute providers, which is not allowed.",
XacmlStatusCode.SYNTAX_ERROR.value());
}
/*
* If datatype classes match, bagResult should have same type as datatypeClass.
*/
final AttributeBag<AV> result = (AttributeBag<AV>) bagResult;
this.listeners.forEach((lt, l) -> l.namedAttributeValueConsumed(attributeFqn, result));
return result;
}
@Override
public boolean putNamedAttributeValueIfAbsent(final AttributeFqn attributeFqn, final AttributeBag<?> result)
{
final Bag<?> duplicate = namedAttributes.putIfAbsent(attributeFqn, result);
if (duplicate != null)
{
/*
* This should never happen, as getAttributeDesignatorResult() should have been called first (for same id) and returned this oldResult, and no further call to
* putAttributeDesignatorResultIfAbsent() in this case. In any case, we do not support setting a different result for same id (but different datatype URI/datatype class) in the same
* context
*/
LOGGER.warn("Attempt to override value of AttributeDesignator {} already set in evaluation context. Overriding value: {}", attributeFqn, result);
return false;
}
this.listeners.forEach((lt, l) -> l.namedAttributeValueProduced(attributeFqn, result));
/*
* Attribute value cannot change during evaluation context, so if old value already there, put it back
*/
return true;
}
/** {@inheritDoc} */
@Override
public XdmNode getAttributesContent(final String category)
{
return extraContentsByAttributeCategory.get(category);
}
/** {@inheritDoc} */
@Override
public <AV extends AttributeValue> Bag<AV> getAttributeSelectorResult(final AttributeSelectorExpression<AV> attributeSelector) throws IndeterminateEvaluationException
{
final Bag<?> bagResult = attributeSelectorResults.get(attributeSelector.getAttributeSelectorId());
if (bagResult == null)
{
return null;
}
final Datatype<Bag<AV>> expectedBagDatatype = attributeSelector.getReturnType();
final Datatype<?> expectedElementDatatype = expectedBagDatatype.getTypeParameter().get();
if (!bagResult.getElementDatatype().equals(expectedElementDatatype))
{
throw new IndeterminateEvaluationException(
"Datatype ("
+ bagResult.getElementDatatype()
+ ")of AttributeSelector "
+ attributeSelector.getAttributeSelectorId()
+ " in context is different from actually expected/requested ("
+ expectedElementDatatype
+ "). May be caused by use of same AttributeSelector Category/Path/ContextSelectorId with different Datatypes in different in different policy elements, which is not allowed.",
XacmlStatusCode.SYNTAX_ERROR.value());
}
/*
* If datatype classes match, bagResult should has same type as datatypeClass.
*/
final Bag<AV> result = expectedBagDatatype.cast(bagResult);
this.listeners.forEach((lt, l) -> l.attributeSelectorResultConsumed(attributeSelector, result));
return result;
}
/** {@inheritDoc} */
@Override
public <AV extends AttributeValue> boolean putAttributeSelectorResultIfAbsent(final AttributeSelectorExpression<AV> attributeSelector, final Bag<AV> result)
throws IndeterminateEvaluationException
{
final AttributeSelectorId attSelectorId = attributeSelector.getAttributeSelectorId();
if (attributeSelectorResults.putIfAbsent(attSelectorId, result) != null)
{
LOGGER.error("Attempt to override value of AttributeSelector {} already set in evaluation context. Overriding value: {}", attSelectorId, result);
return false;
}
for (final Listener listener : this.listeners.values())
{
final Optional<AttributeFqn> optionalContextSelectorFQN = attributeSelector.getContextSelectorFQN();
final Optional<AttributeBag<XPathValue>> contextSelectorValue = optionalContextSelectorFQN.isPresent() ? Optional.of(getNamedAttributeValue(optionalContextSelectorFQN.get(),
StandardDatatypes.XPATH.getBagDatatype())) : Optional.empty();
listener.attributeSelectorResultProduced(attributeSelector, contextSelectorValue, result);
}
return true;
}
/** {@inheritDoc} */
@Override
public <V extends Value> V getVariableValue(final String variableId, final Datatype<V> expectedDatatype) throws IndeterminateEvaluationException
{
final Value val = varValsById.get(variableId);
if (val == null)
{
return null;
}
try
{
return expectedDatatype.cast(val);
}
catch (final ClassCastException e)
{
throw new IndeterminateEvaluationException("Datatype of variable '" + variableId + "' in context does not match expected datatype: " + expectedDatatype,
XacmlStatusCode.PROCESSING_ERROR.value(), e);
}
}
/** {@inheritDoc} */
@Override
public boolean putVariableIfAbsent(final String variableId, final Value value)
{
if (varValsById.putIfAbsent(variableId, value) != null)
{
LOGGER.error("Attempt to override value of Variable '{}' already set in evaluation context. Overriding value: {}", variableId, value);
return false;
}
return true;
}
/** {@inheritDoc} */
@Override
public Value removeVariable(final String variableId)
{
return varValsById.remove(variableId);
}
/** {@inheritDoc} */
@Override
public Object getOther(final String key)
{
return mutableProperties.get(key);
}
/** {@inheritDoc} */
@Override
public boolean containsKey(final String key)
{
return mutableProperties.containsKey(key);
}
/** {@inheritDoc} */
@Override
public void putOther(final String key, final Object val)
{
mutableProperties.put(key, val);
}
/** {@inheritDoc} */
@Override
public Object remove(final String key)
{
return mutableProperties.remove(key);
}
/** {@inheritDoc} */
@Override
public Iterator<Entry<AttributeFqn, AttributeBag<?>>> getNamedAttributes()
{
final Set<Entry<AttributeFqn, AttributeBag<?>>> immutableAttributeSet = Collections.unmodifiableSet(namedAttributes.entrySet());
return immutableAttributeSet.iterator();
}
@Override
public boolean isApplicablePolicyIdListRequested()
{
return returnApplicablePolicyIdList;
}
@Override
public <L extends Listener> L putListener(final Class<L> listenerType, final L listener)
{
return this.listeners.putInstance(listenerType, listener);
}
@Override
public <L extends Listener> L getListener(final Class<L> listenerType)
{
return this.listeners.getInstance(listenerType);
}
}
/**
* Individual decision request evaluator
*
......@@ -489,12 +196,13 @@ public final class BasePdpEngine implements CloseablePdpEngine
private static final IndeterminateEvaluationException newReqMissingStdEnvAttrException(final AttributeFqn attrGUID)
{
return new IndeterminateEvaluationException("The standard environment attribute ( " + attrGUID
+ " ) is not present in the REQUEST although at least one of the others is! (PDP standardEnvironmentAttributeSource = REQUEST_ELSE_PDP.)",
return new IndeterminateEvaluationException(
"The standard environment attribute ( " + attrGUID
+ " ) is not present in the REQUEST although at least one of the others is! (PDP standardEnvironmentAttributeSource = REQUEST_ELSE_PDP.)",
XacmlStatusCode.MISSING_ATTRIBUTE.value());
}
private static final Map<AttributeFqn, AttributeBag<?>> STD_ENV_RESET_MAP = HashCollections.<AttributeFqn, AttributeBag<?>> newImmutableMap(
private static final Map<AttributeFqn, AttributeBag<?>> STD_ENV_RESET_MAP = HashCollections.<AttributeFqn, AttributeBag<?>>newImmutableMap(
StandardEnvironmentAttribute.CURRENT_DATETIME.getFQN(),
Bags.emptyAttributeBag(StandardDatatypes.DATETIME, newReqMissingStdEnvAttrException(StandardEnvironmentAttribute.CURRENT_DATETIME.getFQN())),
StandardEnvironmentAttribute.CURRENT_DATE.getFQN(),
......@@ -641,8 +349,8 @@ public final class BasePdpEngine implements CloseablePdpEngine
this.reqAndPdpIssuedAttributesMerger = REQUEST_OVERRIDES_ATTRIBUTES_MERGER;
break;
default:
throw new IllegalArgumentException("Unsupported standardEnvAttributeSource: " + stdEnvAttributeSource + ". Expected: "
+ Arrays.toString(StandardEnvironmentAttributeSource.values()));
throw new IllegalArgumentException(
"Unsupported standardEnvAttributeSource: " + stdEnvAttributeSource + ". Expected: " + Arrays.toString(StandardEnvironmentAttributeSource.values()));
}
}
......@@ -912,8 +620,9 @@ public final class BasePdpEngine implements CloseablePdpEngine
}
else
{
this.individualReqEvaluator = this.decisionCache.isEvaluationContextRequired() ? new IndividualRequestEvaluatorWithCacheUsingEvaluationContext(rootPolicyEvaluator, stdEnvAttributeSource,
this.decisionCache) : new IndividualRequestEvaluatorWithCacheIgnoringEvaluationContext(rootPolicyEvaluator, stdEnvAttributeSource, this.decisionCache);
this.individualReqEvaluator = this.decisionCache.isEvaluationContextRequired()
? new IndividualRequestEvaluatorWithCacheUsingEvaluationContext(rootPolicyEvaluator, stdEnvAttributeSource, this.decisionCache)
: new IndividualRequestEvaluatorWithCacheIgnoringEvaluationContext(rootPolicyEvaluator, stdEnvAttributeSource, this.decisionCache);
}
}
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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.
*/
package org.ow2.authzforce.core.pdp.impl;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import org.ow2.authzforce.core.pdp.api.AttributeFqn;
import org.ow2.authzforce.core.pdp.api.AttributeProvider;
import org.ow2.authzforce.core.pdp.api.AttributeSelectorId;
import org.ow2.authzforce.core.pdp.api.DecisionCache;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.HashCollections;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.UpdatableCollections;
import org.ow2.authzforce.core.pdp.api.UpdatableMap;
import org.ow2.authzforce.core.pdp.api.expression.AttributeSelectorExpression;
import org.ow2.authzforce.core.pdp.api.value.AttributeBag;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.Bag;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
import org.ow2.authzforce.core.pdp.api.value.StandardDatatypes;
import org.ow2.authzforce.core.pdp.api.value.Value;
import org.ow2.authzforce.core.pdp.api.value.XPathValue;
import org.ow2.authzforce.xacml.identifiers.XacmlStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.MutableClassToInstanceMap;
import net.sf.saxon.s9api.XdmNode;
/**
* An {@link EvaluationContext} associated to an XACML Individual Decision Request, i.e. for evaluation to a single authorization decision Result (see Multiple Decision Profile spec for more
* information on Individual Decision Request as opposed to Multiple Decision Request). This is the default {@link EvaluationContext} implementation used by the PDP engine. It is also meant to be used
* particularly in unit tests of PDP extensions depending on evaluation context, e.g. {@link AttributeProvider}, {@link DecisionCache}, etc.
*
*
* @version $Id: $
*/
public final class IndividualDecisionRequestContext implements EvaluationContext
{
/**
* Logger used for all classes
*/
private static final Logger LOGGER = LoggerFactory.getLogger(IndividualDecisionRequestContext.class);
private final Map<AttributeFqn, AttributeBag<?>> namedAttributes;
/*
* Corresponds to Attributes/Content (by attribute category) marshalled to XPath data model for XPath evaluation: AttributeSelector evaluation, XPath-based functions, etc. This may be empty if no
* Content in Request or no feature requiring XPath evaluation against Content is supported/enabled.
*/
// Not null
private final Map<String, XdmNode> extraContentsByAttributeCategory;
/*
* AttributeSelector evaluation results. Not null
*/
private final UpdatableMap<AttributeSelectorId, Bag<?>> attributeSelectorResults;
private final Map<String, Value> varValsById = HashCollections.newMutableMap();
private final Map<String, Object> mutableProperties = HashCollections.newMutableMap();
private final boolean returnApplicablePolicyIdList;
private final ClassToInstanceMap<Listener> listeners = MutableClassToInstanceMap.create();
/**
* Constructs a new <code>IndividualDecisionRequestContext</code> based on the given request attributes and extra contents with support for XPath evaluation against Content element in Attributes
*
* @param namedAttributeMap
* updatable named attribute map (attribute key and value pairs) from the original Request; null iff none. An attribute key is a global ID based on attribute category,issuer,id. An
* attribute value is a bag of primitive values.
* @param extraContentsByCategory
* extra contents by attribute category (equivalent to XACML Attributes/Content elements); null iff no Content in the attribute category.
* @param returnApplicablePolicyIdList
* true iff list of IDs of policies matched during evaluation must be returned
*/
public IndividualDecisionRequestContext(final Map<AttributeFqn, AttributeBag<?>> namedAttributeMap, final Map<String, XdmNode> extraContentsByCategory, final boolean returnApplicablePolicyIdList)
{
this.namedAttributes = namedAttributeMap == null ? HashCollections.<AttributeFqn, AttributeBag<?>>newUpdatableMap()
: HashCollections.<AttributeFqn, AttributeBag<?>>newUpdatableMap(namedAttributeMap);
this.returnApplicablePolicyIdList = returnApplicablePolicyIdList;
if (extraContentsByCategory == null)
{
this.extraContentsByAttributeCategory = Collections.emptyMap();
this.attributeSelectorResults = UpdatableCollections.emptyMap();
} else
{
this.extraContentsByAttributeCategory = extraContentsByCategory;
this.attributeSelectorResults = UpdatableCollections.newUpdatableMap();