Camel: Implementing Polling and Non-Polling Consumer within the same component - java

I am implementing my own custom component and I have found that I am going to need two use cases for consumers:
The first one would be trying to get N number of available messages every so often (Polling Consumer)
The second one would be a subscriber consumer that gets messages when they are available.
My main question is if it possible to implement these two types. I have been trying to write some code, but it seems that if you are developing a PollingConsumer you cannot implement another type. Also, if it is possible, is there any example, article or guide about how to do this? I have been looking for it for nothing came up.
Thanks!

There is two consumer kind in Camel (eg from the EIP book)
Consumer
PollingConsumer
Its the former that is used in the Camel routes. And the latter is used when you use it explicit or when using ConsumerTemplate, to use the receive methods.
A Camel component is able to adapt a Consumer to a PollingConsumer out of the box.
So it depends if you want to build a Camel component that are used in routes, you can just create a consumer. And have it able to do both poll and subscribe. When you have the data, then create an Exchange and call the processor to route it.
For documentation then check the Camel website, and/or chapter 11 in the Camel in Action book which covers creating custom components.

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

Handling a big amount of JMS message types

i'm new to jms, and i'm currently designing a BattleShip game.
I'm using jms with activemq for the communication between them, so far i made 4 classes for jms communication which are Topic and Queue receivers and senders with simple methods of changing destination and sending.
Now i'm facing a problem when want to handle these messages,
I've decided every message will be delivered via ObjectMessage and the inner object will tell the listener how to handle it.
I have 5 different categories for messages :
Authentication,
Data (Such as highscores, replays etc),
InGameMessages (ShipRegistration, TurnUpdate and so on),
ChatMessage,
MatchMakingMessages (Only GameSearch and GameSearchCancel),
So i thought it will be a good idea to add a MessageType enum to each message,
but eventually I ended up writing the listener with over than 20 cases at the switch statement and with a huge amount of class castings.
Now I want to write it all over again, but i'm still stuck on the message handling since I can't find a different idea, or any design pattern which can handle this issue.
Any thoughts?
You can set a JMS property with the value of your "MessageType" enum. JMSType is a built-in property that you can use for that or you can add your own property to every message (with a name like "MessageType")
On the client side, read the message and test the value of that property and convert it back to the enum in a switch statement then perform the casting of the message based on the object of the class associated with the message, Use only one topic, each client subscribing to the topic.
Instead of the switch statement, you can have one listener per message type based on a JMS selector, each one selecting only one value of the JMS property (ie MessageType). All depends of your use case of course (strict ordering etc.)
You can use different topics/queues for different message categories.
You can also add properties to your message.
You can use a framework like spring that can do this for you, specially MessageListenerAdapter. Have a look at spring jms.
EDIT :
I can see some Design Pattern you can have a look at : Chain of Responsability, maybe Observer or EventListener.
The point here is that you have only one handler, that will handle all kinds of messages, read a property and then decide how to handle it. The solution may be to have many handlers, one by kind of message, and to find a way to route messages to the right handler.
Chain of Responsability can do the trick here : pass the message to the first handler of the chain, if it is concerned by the message then it can handle it, otherwise it will pass the message to the next handler, and so on.

Multiple ways to communicate with Akka Actor from outside the system?

I was under the impression that the only way to communicate with an Akka Actor from outside the ActorSystem was via Inbox. However I just found this snippet from Akka's own documentation which shows:
greeter.tell(new WhoToGreet("akka"), ActorRef.noSender());
inbox.send(greeter, new Greet());
So which is it? Is it in fact possible to directly tell an Actor from the outside world, or did Typesafe have a careless intern writing their documentation for them?!?
If it is possible, then when should you do this, and when should you use Inbox? For instance, is one method "fire-and-forget" asynchronous/non-blocking and the other synchronous/blocking?
Inbox is part of the relatively recent Actor DSL API that is "some nice sugar on top of the usual ways to create actors". You can either use the standard way to create / communicate with actors or use the Actor DSL. They are both async. The Actor DSL is nice for creating one-off actors whose lifetime is one method. The advantage of the DSL syntax is a bit more evident in Scala.
You can safely send messages from outside an actor. Akka will fill in a dummy sender. You just won't be able to receive any replies (though you can use an ask for that).

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).

How to Aspect a whole camel route

Essentially, I'd like to aspect a whole camel route, so that I can grab the payload at the start and the end.
Now, I know I can just aspect the main "doing" class in the middle, not pulling it from a queue and placing it on the disk at the end. And this is fine for a simple route, not one that has many "doing" classes.
But is there a way to tie up the start and end of a route, without putting this into the route?
I have got a lot of routes and I'd like to keep them as clean of logging code as possible.
Use the interception possibilities of Camel as described here:
intercept that intercepts each and every processing step while routing an Exchange in the route.
interceptFrom that intercepts incoming Exchange in the route.
interceptSendToEndpoint that intercepts when an Exchange is about to be sent to the given Endpoint.
In your case the second and third possibility may be of interest.
I think you've got two choices:
Add a wiretap at the start and end of each route. See http://camel.apache.org/wire-tap.html. This obviously means editing the routes but is simple easy and it only two lines per route.
Use RouteDefinition.adviceWith to dynamically add an interceptor. See http://camel.apache.org/advicewith.html. I've not seen this used outside testing but I don't see any reason why you can't use it in live code.

Categories