Search code examples
javaspringcucumberspring-integrationcucumber-junit

load Spring aggregator parametrs dynamically for tests


I'm using the aggregator of spring integration in my app. I'm using cucumber to test the flow, and I want to make sure that the aggregator release strategy is executed by the right parameters. I have 2 params for that strategy: timeout, and size. I would like to know if there is a way to load those parameters dynamically during the steps? So far I'm lost about how to make it work.

Thanks,

Thank you Artem,

I used the directFieldAccessor and I'm trying to get the release-strategy-expression and group-timeout attributes from the aggregator, but the problem is that I can't access those fields:

public void setAggregatorConfiguration(String aggregatorName, int aggregationThreshold, long aggregationTimeout) { 
         EventDrivenConsumer aggregator = getAggregator(aggregatorName);           
         DirectFieldAccessor directFieldAccessor = new DirectFieldAccessor(aggregator); 
         directFieldAccessor.setPropertyValue("group-timeout", aggregationTimeout); 
} 

Solution

  • I have 2 params for that strategy: timeout, and size

    Well, I guess you use TimeoutCountSequenceSizeReleaseStrategy. As we see those params are final in that class and they really can't be changed at runtime just with setters.

    There is only one way to change such values at runtime - using DirectFieldAccessor.

    However if you share more info about your use-case and config and unit test as well, we might find some other way to help you.

    I've edited your post to add your code. No, you have to use the real property name, so it should be groupTimeoutExpression, not group-timeout. From other side there is a public setter on the matter: AbstractCorrelatingMessageHandler.setGroupTimeoutExpression(Expression groupTimeoutExpression).

    From other side you go a bit wrong way: any MessageHandler component (<aggregator>, <service-activator>) provides several component. Right, the root of them is a AbstractEndpoint (the parent of EventDrivenConsumer). But all of your desired properties are to the AggregatingMessageHandler, which can get from BeanFactory using its alias - aggregatorName + ".handler".

    release-strategy-expression is property of ExpressionEvaluatingReleaseStrategy, which you can change using DirectFieldAccessor on the AggregatingMessageHandler:

    AggregatingMessageHandler handler = beanFactory.getBean(aggregatorName + ".handler", AggregatingMessageHandler.class);
    DirectFieldAccessor directFieldAccessor = new DirectFieldAccessor(handler); 
    ReleaseStrategy releaseStrategy = (ReleaseStrategy) directFieldAccessor.getPropertyValue("releaseStrategy");
    DirectFieldAccessor dfa = new DirectFieldAccessor(releaseStrategy); 
    dfa.setPropertyValue("expression", ...);
    

    Anyway, it isn't clear, why you need such a perversion...