You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by lq...@apache.org on 2017/04/14 14:26:46 UTC
svn commit: r1791371 -
/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java
Author: lquack
Date: Fri Apr 14 14:26:46 2017
New Revision: 1791371
URL: http://svn.apache.org/viewvc?rev=1791371&view=rev
Log:
QPID-7741: [Java Broker] validate mandatory fields of AMQP 1.0 composite types
Modified:
qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java
Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java?rev=1791371&r1=1791370&r2=1791371&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/codec/AbstractDescribedTypeConstructor.java Fri Apr 14 14:26:46 2017
@@ -20,17 +20,30 @@
*/
package org.apache.qpid.server.protocol.v1_0.codec;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException;
import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
+import org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException;
+import org.apache.qpid.server.protocol.v1_0.type.CompositeTypeField;
+import org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError;
public abstract class AbstractDescribedTypeConstructor<T extends Object> implements DescribedTypeConstructor<T>
{
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDescribedTypeConstructor.class);
+
@Override
public TypeConstructor<T> construct(final Object descriptor,
final List<QpidByteBuffer> in,
- final int[] originalPositions, final ValueHandler valueHandler) throws AmqpErrorException
+ final int[] originalPositions, final ValueHandler valueHandler)
+ throws AmqpErrorException
{
return new TypeConstructorFromUnderlying<>(this, valueHandler.readConstructor(in));
@@ -43,6 +56,7 @@ public abstract class AbstractDescribedT
private final TypeConstructor _describedConstructor;
private AbstractDescribedTypeConstructor<S> _describedTypeConstructor;
+ private static final Map<Class<?>, CompositeTypeValidator> _validators = new ConcurrentHashMap<>();
public TypeConstructorFromUnderlying(final AbstractDescribedTypeConstructor<S> describedTypeConstructor,
final TypeConstructor describedConstructor)
@@ -54,7 +68,57 @@ public abstract class AbstractDescribedT
@Override
public S construct(final List<QpidByteBuffer> in, final ValueHandler handler) throws AmqpErrorException
{
- return _describedTypeConstructor.construct(_describedConstructor.construct(in, handler));
+ final S constructedObject =
+ _describedTypeConstructor.construct(_describedConstructor.construct(in, handler));
+ CompositeTypeValidator<S> validator =
+ _validators.computeIfAbsent(constructedObject.getClass(), k -> createValidator(constructedObject));
+ validator.validate(constructedObject);
+ return constructedObject;
+ }
+
+ private CompositeTypeValidator<S> createValidator(final S constructedObject)
+ {
+ final List<Field> mandatoryFields = new ArrayList<>();
+ for (Field field : constructedObject.getClass().getDeclaredFields())
+ {
+ Annotation[] annotations = field.getDeclaredAnnotationsByType(CompositeTypeField.class);
+ for (Annotation annotation : annotations)
+ {
+ if (annotation instanceof CompositeTypeField && ((CompositeTypeField) annotation).mandatory())
+ {
+ field.setAccessible(true);
+ mandatoryFields.add(field);
+ }
+ }
+ }
+ return objectToValidate ->
+ {
+ try
+ {
+ if (!mandatoryFields.isEmpty())
+ {
+ for (Field field : mandatoryFields)
+ {
+ if (field.get(objectToValidate) == null)
+ {
+ throw new AmqpErrorException(AmqpError.DECODE_ERROR,
+ String.format("Missing mandatory field '%s'.",
+ field.getName()));
+ }
+ }
+ }
+ }
+ catch (IllegalAccessException e)
+ {
+ LOGGER.error(String.format("Error validating AMQP 1.0 object '%s'", constructedObject.toString()), e);
+ throw new AmqpErrorException(AmqpError.INTERNAL_ERROR, "Failure during object validation");
+ }
+ };
+ }
+
+ private interface CompositeTypeValidator<S>
+ {
+ void validate(final S constructedObject) throws AmqpErrorException;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org