Xacml30PolicyMarshaller fails with "unable to marshal type "java.lang.Long" as an element because it is missing an @XmlRootElement annotation"
IlyaAI opened this issue · comments
Steps to reproduce overview:
- Using builders construct policy containing
- Serialize this policy to xml with Xacml30PolicyMarshaller
- Marshaller fails
Reproducing test:
import org.junit.Test;
import org.xacml4j.v30.Effect;
import org.xacml4j.v30.marshal.jaxb.Xacml30PolicyMarshaller;
import org.xacml4j.v30.pdp.Apply;
import org.xacml4j.v30.pdp.Policy;
import org.xacml4j.v30.pdp.Rule;
import org.xacml4j.v30.policy.combine.DenyOverridesRuleCombiningAlgorithm;
import org.xacml4j.v30.spi.function.FunctionProvider;
import org.xacml4j.v30.spi.function.FunctionProviderBuilder;
import org.xacml4j.v30.types.IntegerExp;
import org.xacml4j.v30.types.StringExp;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.notNullValue;
public class MarshalAttributeValueTest {
private final static FunctionProvider Funcs = FunctionProviderBuilder.builder()
.defaultFunctions()
.build();
//
// This test fails with error "unable to marshal type "java.lang.Long" as an element because it is missing an @XmlRootElement annotation"
//
@Test
public void marshalIntegerAttributeValue() throws IOException {
// arrange
Rule rule = Rule.builder("rule", Effect.DENY)
.condition(
Apply.builder(Funcs.getFunction("urn:oasis:names:tc:xacml:1.0:function:integer-equal"))
.param(IntegerExp.of(0))
.param(IntegerExp.of(1))
.build()
)
.build();
Policy policy = Policy.builder("policy")
.combiningAlgorithm(new DenyOverridesRuleCombiningAlgorithm())
.rule(rule)
.build();
// act
Writer writer = new StringWriter();
new Xacml30PolicyMarshaller().marshal(policy, writer);
String xml = writer.toString();
// assert
assertThat(xml, notNullValue());
}
//
// ...but this one is ok.
//
@Test
public void marshalStringAttributeValue() throws IOException {
// arrange
Rule rule = Rule.builder("rule", Effect.DENY)
.condition(
Apply.builder(Funcs.getFunction("urn:oasis:names:tc:xacml:1.0:function:string-equal"))
.param(StringExp.of("a"))
.param(StringExp.of("b"))
.build()
)
.build();
Policy policy = Policy.builder("policy")
.combiningAlgorithm(new DenyOverridesRuleCombiningAlgorithm())
.rule(rule)
.build();
// act
Writer writer = new StringWriter();
new Xacml30PolicyMarshaller().marshal(policy, writer);
String xml = writer.toString();
// assert
assertThat(xml, notNullValue());
}
}
I'm using version 1.3.2 from https://jcenter.bintray.com
I suppose the problem in ExpressionTypeBuilder:
ATTRIBUTE(AttributeExp.class){
@Override
public JAXBElement<?> from(Expression e){
Preconditions.checkArgument(e instanceof AttributeExp);
AttributeExp v = (AttributeExp)e;
AttributeValueType exp = factory.createAttributeValueType();
exp.setDataType(v.getType().getDataTypeId());
exp.getContent().add(v.getValue());
return factory.createAttributeValue(exp);
}
}
it adds attribute value to content as is, but really should use TypeToXacml30 to convert value to string representation.
Thank you for a detailed report!