What is Camel KafkaIdempotentRepository and the uses of it? - java

I'm trying to get the msg with the latest offset in kafka. Can this be used to get that? 'KafkaIdempotentRepository'
If not what's the use of it?
In the java doc it says the following. But it's not clear what's the real use of it.

Camel Idempotent Repository implementations are used as consumer to filter out duplicate messages. And KafkaIdempotentRepository is one of the many implementations Camel provide (e.g. others are MemoryIdempotentRepository, FileIdempotentRepository, HazelcastIdempotentRepository, JCacheIdempotentRepository, InfinispanIdempotentRepository, etc...).
For more detailed reading please refer to below links:
https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2/html/Apache_Camel_Development_Guide/MsgEnd-Idempotent.html
http://people.apache.org/~dkulp/camel/idempotent-consumer.html
Coming back to your questions:
I'm trying to get the msg with the latest offset in kafka. Can this be used to get that? 'KafkaIdempotentRepository' If not what's the use of it?
In my personal opinion, I don't think KafkaIdempotentRepository is meant to serve this use case.
Kafka does guarantee ordering which means message served will have the latest committed offset within a partition.

Related

How can create a producer using Spring Cloud Kafka Stream 3.1

I know how to define a producer using the imperative programming approach but I cannot find how to define a producer using the functional programming approach.
I read the Spring Cloud Stream Binder documentation about this, but only found how to define consumer, or consumer & producer (for example, get information from the topic, transform the data and send to another topic).
So, I don't know if it's ok to continue use annotations like #Input, #Ouptut to define a single processor or not, I'm very confused at this point because the library indicates these annotations are deprecated, but I cannot find the example or documentation to define a simple producer to send information to a specific topic.
Thanks!
The documentation link:
https://docs.spring.io/spring-cloud-stream-binder-kafka/docs/3.0.10.RELEASE/reference/html/spring-cloud-stream-binder-kafka.html#_kafka_streams_binder
You can define a Supplier<?> #Bean which will be polled on an interval to generate output (like the #InboundChannelAdapter for #Output channels.
https://docs.spring.io/spring-cloud-stream/docs/3.1.0/reference/html/spring-cloud-stream.html#spring_cloud_function
Or, you can use a StreamBridge to send arbitrary messages to an output destination.
https://docs.spring.io/spring-cloud-stream/docs/3.1.0/reference/html/spring-cloud-stream.html#_sending_arbitrary_data_to_an_output_e_g_foreign_event_driven_sources

How can I configure the RingBuffer used by ReliableTopic in Hazelcast? I have multiple topics

I am creating multiple reliable topics in Hazelcast. As I understand from the documentation, it is backed by a ringbuffer. How can I configure the ringbuffer for a topic to suit my needs?
I want to persist only top 100 messages for one topic and entire history for another.
You can configure the reliable topic backing ring buffers by using the prefix _hz_rb_ in front of your reliable topic's name. For instance; assume that you have a reliable topic with the name myReliableTopic. The ring buffer backing this reliable topic will have the name as _hz_rb_myReliableTopic. So, you can configure it as below:
<ringbuffer name="_hz_rb_myReliableTopic">
<capacity>100</capacity>
</ringbuffer>
You can access this prefix using the RingbufferService.TOPIC_RB_PREFIX static field in the application.
Please remind that this prefix is not a part of the public API, thus it is not guaranteed to be kept unchanged in future releases.
Keeping the name same for ReliableTopic & RingBuffer does not work. While getting RingBuffer Object we have to prefix it with _hz_rb_as said by Alparslan Avci ealier is the only solution. Hazelcast document says otherwise but it does not work. Looks like a bug in Hazelcast.
Rakesh

Best way handle partitioned data with AMQP?

I have several similar systems which are authoritative for different parts of my data, but there's no way I can tell just from my "keys" which system owns which entities.
I'm working to build this system on top of AMQP (RabbitMQ), and it seems like the best way to handle this would be:
Create a Fanout exchange, called thingInfo, and have all of my other systems bind their own anonymous queues to that exchange.
Send a message out to the exchange: {"thingId": "123abc"}, and set a reply_to queue.
Wait for a single one of the remote hosts to reply to my message, or for some timeout to occur.
Is this the best way to go about solving this sort of problem? Or is there a better way to structure what I'm looking for? This feels mostly like the RPC example from the RabbitMQ docs, except I feel like using a broadcast exchange complicates things.
I think I'm basically trying to emulate the model described for MCollective's Message Flow, but, while I think MCollective generally expects more than one response, in this case, I would expect/require precisely one or, preferably, a clear "nope, don't have it, go fish" response from "everyone" (if it's really possible to even know that in this sort of architecture?).
Perhaps another model that mostly fits is "Scatter-Gather"? It seems there's support for this in Spring Integration.
It's a reasonable architecture (have the uninterested consumers simply ignore the message).
If there's some way to extract the pertinent data that the consumers use to decide interest into headers, then you can gain some efficiency by using a topic exchange instead of a fanout.
In either case, it gets tricky if more than one consumer might reply.
As you say, you can use a timeout if zero consumers reply, but if you think that might be frequent, you may be better off using arbitrary two-way messaging and doing the reply correlation in your code rather than using request/reply and tying up a thread waiting for a reply that will never come, and timing out.
This could also deal with the multi-reply case.

Queue for messages from two sources in Apache Camel with chronological order

I would like to realize next scenario in Apache Camel (included in JBoss Fuse):
I have two systems, both of them produce events stored in database separately. Now I need to read events from this event tables and put them as messages in queue (realized by ActiveMQ). But what is really important I need to keep chronological order (creation time) of events in this queue, no matters where event was created.
I am looking for solution, which maximally uses components and patterns from Camel framework, of course I can realize the reading mechanism outside of Camel (pure Java), but I prefer Camel solution.
Thanks a lot for any idea!
I think you just want to pop the messages onto a seda queue and use a resequencer to merge them back into order.
from("--database1--")
to("seda:resequencer")
from("--database2--")
to("seda:resequencer")
from("seda:resequencer")
.resequence(header("date")).batch().timeout(5000L)
.to("activemq:...")
You will need to pay attention to the timeout settings and what is appropriate.
(Note: I haven't tested this code, so please tage it as a suggestion).

Cometd filter data for specific client in channel

I'm designing a system using comet where there is a common channel where data getting published. I need to filter the data using some conditions based on client subscription details. Can anyone tell how I can do this? I thought I can do this using DataFilter.
Channel.addDataFilter(DataFilter filter);
Is this the correct way? If so any sample code to achieve this please?
There is no Channel.addDataFilter(DataFilter) method, but you can achieve the same results in a different way.
First, have a look at the available DataFilter implementations already available.
Then it's enough that you add a DataFilterMessageListener to the channel you want to filter data on, and specify one or more DataFilter to the DataFilterMessageListener.
You can find an example of this in the CometD demos shipped with the CometD distribution, for example here.
The right way to add the DataFilterMessageListener is during channel initialization, as it is done in the example linked above through a #Configure annotation, or equivalently via ServerChannel.Initializer.
Finally, have a look at how messages are processed on the server from the documentation: http://docs.cometd.org/reference/#concepts_message_processing.
It is important to understand that modifications made by DataFilter are seen by all subscribers.

Categories