1

I'm using Project Reactor with Spring Integration to read from Kafka and write to MongoDB, and I the Kafka consume works well, but the .handle(MongoDb.reactiveOutboundChannelAdapter(mongoFactory)) stucks. I've seen that the internal code of this function is new ReactiveMongoDbStoringMessageHandler(mongoFactory)), so I've tried the following (I have a transform() method that converts from ConsumerRecord to Mono<String>, with the @Transformer annotation):

    public IntegrationFlows writeToMongo() {
         return IntegrationFlows.from(kafkaChannel)
              .transform(this)
              .handle(new ReactiveMongoDbStoringMessageHandler(mongoFactory))
              .get();
    }

The code follows the docs https://docs.spring.io/spring-integration/reference/html/mongodb.html#mongodb-reactive-channel-adapters. The error I get is: java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.Void] for method match: and then a very long list of functions. Any reason this could happen?

2 Answers2

0

You cannot do new ReactiveMongoDbStoringMessageHandler(mongoFactory) if you are not going to subscribe to the returned Mono. A .handle(MongoDb.reactiveOutboundChannelAdapter(mongoFactory)) is the right way to do since it wraps that ReactiveMongoDbStoringMessageHandler into a ReactiveMessageHandlerAdapter for automatic subscription.

However I think your real problem is with the .transform(this). I believe you have a lot of methods in this class, so be more specific with method name. And this has nothing to do with Project Reactor. Not sure though why would one try to convert to Mono before sending to that ReactiveMongoDbStoringMessageHandler... You probably have problem in providing the payload (ConsumerRecord ?) which is not MongoDB mapped entity for saving into the collection.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Yes I do have a problem with the `ConsumerRecord` type that I want to convert to a String that Mongo will be able to map. I don't understand how `reactiveOutboundChannelAdapter(mongoFactory)` wraps `ReactiveMongoDbStoringMessageHandler` into a `ReactiveMessageHandlerAdapter` for automatic subscription (just out of curiosity because I don't see that in the code). Anyway, when I convert back to `.handle(MongoDb.reactiveOutboundChannelAdapter(mongoFactory))`, the client stucks. Do you have any idea why? – user17954501 Jan 19 '22 at 10:25
  • I've fixed to mongo writes by specifying a collection by `.collectionName("colName")`. I'd add this to the documentation. I also think that there are very limited amount of Reactive Spring Integration examples with the Java DSL (and even limited amount of non reactive exmaples with the DSL). I'd suggest to add some if it's not hard. – user17954501 Jan 19 '22 at 12:59
  • The `ReactiveMessageHandlerAdapter` does that automatic subscription in its `handleMessage()` impl: `this.delegate.handleMessage(message).subscribe();`. – Artem Bilan Jan 19 '22 at 14:31
  • The `ReactiveMongoDbMessageHandlerSpec` is an extension of `ReactiveMessageHandlerSpec` which does the wrapping for us: `this.target = new ReactiveMessageHandlerAdapter(this.reactiveMessageHandler);` – Artem Bilan Jan 19 '22 at 14:32
  • The default collection name (`data`) is explained in the docs: https://docs.spring.io/spring-integration/docs/current/reference/html/mongodb.html#mongodb-reactive-channel-adapters. > In this sample we are going to connect to the MongoDb via provided `ReactiveMongoDatabaseFactory` and store a data from request message into a default collection with the data name. – Artem Bilan Jan 19 '22 at 15:02
  • Yes, we don't have enough resources to write all the kind of samples. See some unit tests on the matter in the project: https://github.com/spring-projects/spring-integration/blob/main/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/ReactiveMongoDbStoringMessageHandlerTests.java – Artem Bilan Jan 19 '22 at 15:04
  • Thank you for your time. I understand now the `ReactiveMessageHandlerAdapter` trick. I actually did saw these two links that you've provided. I think that the docs are missing of examples for more complex MongoDb operations (such as updates). The tests didn't help me because they use lots of XMLs. I think that one big example of a reactive java DSL data pipeline can be super helpful for new users. – user17954501 Jan 19 '22 at 15:51
0

Happened to me either. Solution was (notice the ReactiveMessageHandlerAdapter):

public IntegrationFlows writeToMongo() {
     return IntegrationFlows.from(kafkaChannel)
          .handle(new ReactiveMessageHandlerAdapter(new ReactiveMongoDbStoringMessageHandler(mongoFactory)))
          .get();
}

This can be replaced by handleReactive() when this issue will be resolve.