Search code examples
spring-cloud-streamspring-cloud-dataflowspring-rabbit

How to use a SPEL expression that is applied on a POJO for the routingKey?


My Source APP:

@InboundChannelAdapter(value = RequestSource.CHANNEL_NAME)
public Event eventMessageSource() throws Exception {
    final Random r = new Random();
    Event event = generateSampleEvent(EventType.values()[r.nextInt(EventType.values().length - 1)]);
    System.out.println("---- Putting now ==> " + event);
    return event;
}

My application.properties:

logging.level.=INFO
server.port=0
logging.file=events.log
server.port=0
spring.cloud.stream.bindings.requestChannel.destination=events-exchange
spring.cloud.stream.bindings.requestChannel.content-type=application/json
spring.cloud.stream.bindings.requestChannel.binder=rabbit
spring.cloud.stream.bindings.requestChannel.group=eventconsumersgroup
spring.cloud.stream.rabbit.bindings.requestChannel.producer.routing-key-expression=payload.eventType

Exception is this:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'eventType' cannot be found on object of type 'byte[]' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:46)

Should I not use application/json for using a SPEL? Am I missing the right set of properties here?


Solution

  • The payload is already converted to a byte[] before the routing key expression is evaluated.

    You can use message headers.

    @InboundChannelAdapter(value = RequestSource.CHANNEL_NAME)
    public Message<Event> eventMessageSource() throws Exception {
        final Random r = new Random();
        Event event = generateSampleEvent(EventType.values()[r.nextInt(EventType.values().length - 1)]);
        System.out.println("---- Putting now ==> " + event);
        return new GenericMessage<>(event, Collections.singletonMap("type", event.getType());
    }
    

    and then the expression is headers.type or headers['type'].