0

Hi I have a little problem. I want to invoke spring controller manually but I have an exception. Firstly, let me show you some integration flow and controller:

@Bean
public IntegrationFlow flow() {
    return IntegrationFlows.from(
            Amqp.inboundAdapter(rabbitMqConfig.connectionFactory(), queue)
                    .acknowledgeMode(AcknowledgeMode.MANUAL)
                    .errorChannel("errorChannel")
                    .concurrentConsumers(2)
                    .maxConcurrentConsumers(3))
            .transform(Transformers.fromJson(Event.class))
            .transform(new EventToRequestTransformer())
            .handle(Request.class, (request, headers) -> controller.trigger(request))
            .<ResponseEntity, HttpStatus>transform(ResponseEntity::getStatusCode)
            .routeToRecipients(some routing)
            .get();
}


@Controller
public class SomeController {

    @RequestMapping(value = "/trigger", method = RequestMethod.POST)
    public ResponseEntity<Response> trigger(@RequestBody Request request) 
    {
        //some logic
    }
}

When I'm running my app and sending an event I am getting exception on line:

.handle(Request.class, (request, headers) -> controller.trigger(request))

Exception:

nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet

Could someone please tell me what is wrong and how to fix that? I thought I can just invoke controller method like it was coming from simple POJO.

Mariusz Grodek
  • 629
  • 4
  • 12
  • 26

1 Answers1

3

You are mixing concerns and try to call Web tier from the service layer.

If the logic is like that, then design of the app is wrong.

You should extract some service from the controller logic and call it from the Web, as well as from there on the Integration level.

According your stack trace it looks like you try to get access to the request scope object. Well, and that is exactly what happens to @Controller beans, I guess.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • in our project we are replacing controller with message broker and this is temporary solution where we have both. I didn't want to duplicate the code and just pass request to controller which will do the rest. I also think that logic extraction is a way to go but I thought maybe there are some alternative approaches. Thanks for that comment! – Mariusz Grodek Feb 27 '18 at 22:17
  • There is no alternative to the `request` scope outside of the Servlet context. – Artem Bilan Feb 27 '18 at 22:22