How to reuse KafkaListenerContainerFactory with a custom message converter for batch listeners and non-batch/record listeners? - spring-kafka

The spring-kafka documentation mentions:
Starting with version 2.8, you can override the factory’s batchListener propery using the batch property on the #KafkaListener annotation. This, together with the changes to Container Error Handlers allows the same factory to be used for both record and batch listeners.
I want to use it like this. So reuse the same factory for record and batch listeners. The factory is provided by an internal library that is used by multiple services.
However, I also need to define a custom MessageConverter.
But I found out that for batch listeners I need to wrap my message converter in BatchMessagingMessageConverter otherwise the message converter will not be used correctly and the wrong type will be supplied to my batch listener.
So: Is there a simple way to reuse KafkaListenerContainerFactory with a custom messageConverter for batch listeners and non-batch/record listeners?
My current workaround looks like this, but I do not like it as it depends on how spring-kafka internally sets up its configuration, so it might break in future updates:
factory.setContainerCustomizer(container -> {
var messageListener = container.getContainerProperties().getMessageListener();
if (messageListener instanceof FilteringBatchMessageListenerAdapter) {
var meessageListenerDelegate =
((FilteringBatchMessageListenerAdapter<?, ?>) messageListener).getDelegate();
if (meessageListenerDelegate instanceof BatchMessagingMessageListenerAdapter) {
((BatchMessagingMessageListenerAdapter<?, ?>) meessageListenerDelegate).setBatchMessageConverter(
new BatchMessagingMessageConverter(messageConverter));
}
}
});
Another option is to create a separate factory for batch listeners. With this, I am afraid that someone might use #KafkaListener(batch="true") without supplying the correct library, which only works partly.
Currently, I am using version 2.8.9 of spring-kafka.

It is not currently possible; please open a new feature suggestion on GitHub to allow provisioning both types of converter on the factory.

Related

How do I write middleware for Rebus?

I want to be able to write custom middleware for Rebus which will wrap around message handlers: executing before and after each handler, regardless of the message type. Is this possible with Rebus, and if so, how do I do that?
Browsing the source code of Rebus, I think it should be possible, as the library is very neatly built around the concept of IPipeline with customizable "steps". But although it looks like it should be easy to add custom steps, I cannot find any public API exposing the pipline. Is this possible to modify the pipeline from the client code?
What I am looking for is essentially an equivalent to MassTransit's IFilter<>. We are about to choose between MassTransit and Rebus (or possibly a custom implementation on top of Microsoft.Azure.ServiceBus) for a new project, and at this moment this looks like a major feature missing from Rebus.
With Rebus, you add custom steps by decorating IPipeline, which makes it possible to change both incoming and outgoing messages pipelines however you want.
To make it more convenient to inject steps into a specific position in the pipeline, Rebus comes with a PipelineStepInjector, which is a decorator that enables positioning the injected step relative to another step.
Check out the Pipelines section on the wiki page about extensibility – it shows how an outgoing step can be used to automatically enrich the headers of all outgoing messages.
Incoming steps can be added in a similar manner, only using the OnReceive method instead of OnSend to add the step:
Configure.With(...)
.(...)
.Options(o => {
o.Decorate<IPipeline>(c =>
{
var pipeline = c.Get<IPipeline>();
var step = new YourIncomingStep();
return new PipelineStepInjector(pipeline)
.OnReceive(step, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep));
});
})
.Start();

Can I modify a Policy after it is built?

I'm creating an API method call which takes a Policy as an argument.
However, in my method I'd like to 'add onto' this policy by including my own retry Action(s) so that I can perform intermediate logging and telemetry of my own. Similar in concept to adding Click events to a Windows UI control.
Is there a way to modify a Policy after it's created?
Or, is there a hook mechanism where I can define my own callbacks in the Execute method perhaps?
A Polly Policy is immutable; it cannot be modified after configuration. However, there are several ways in which you can attach extra behaviour to a policy.
There could be several approaches depending what you want to achieve.
Note: All examples in this answer refer to synchronous policies / policy-hooks used when executing delegates synchronously, but all the same behaviour exists for the async forms of policies.
Option 1: All policy types do offer delegate hooks such as onRetry; onBreak; onCacheHit, and similar. Extra behaviour (for example logging) can be added in these. The delegates attached to these hooks must be defined at policy configuration time. There are many examples in the Polly readme and Polly-Samples project. The Polly wiki covers all such delegate hooks in depth.
Option 2: If the fact that these delegates (onRetry etc) must be defined at policy configuration time is a restriction: you can overcome this using Polly.Context. Most of the delegates such as onRetry exist in a form which takes Context as an input parameter. That Context is execution-scoped, can carry arbitrary data, and a Context instance can be passed in to the call to .Execute(...).
So you could define Context["ExtraAction"] = /* some Action */ and pass that in to .Execute(...). Then, the onRetry delegate could extract Action extraAction = Context["ExtraAction"] (with some defensive checks) and execute it extraAction(). This allows you to inject arbitrary behaviour to the onRetry delegate after the policy has been configured.
Option 3: Perform your extra logic in the delegate executed. Of course, you could write your own Execute(...) wrapper method which takes a delegate to execute, and a policy, but wraps in extra behaviour.
public TResult MyExecute(ISyncPolicy policy, Func<TResult> toExecute)
{
return policy.Execute(() =>
{
/* do my extra stuff */
return toExecute();
}
}

SimpleIoc (mvvmlight) - how to automatically register all classes implementing a particular interface

Using SimpleIoc I want to automatically register all classes that implement a particular interface. I couldn't see a method on SimpleIoc's container to do this automatically so I put a some code together to iterate through the types to be registered. Unfortunately the code's not happy (see the commented line).
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(typeof(IFoo).IsAssignableFrom);
foreach (var type in types.Where(x=>x.IsClass))
{
container.Register<IFoo, type>(); //this line won't compile as type can't be resolved by the compiler
}
I realise there are less elegant ways of registering classes (such as just hard coding "container.Register" to register each class to the interface) but I'd like to be able to add new implementations without having to keep updating the ioc installer code. It would also be useful, at some point, for me to be able to register classes in other assemblies using the same method.
Any idea what I have to change to make this build (or is there a simpler/more elegant way to do this)?
UPDATE fex posted this comment:
"you can always iterate over types (like you do in your question) and create it with reflection (in your factory class) - (IFoo)Activator.CreateInstance(type); - in fact that's how service locators / ioc containers do it internally (in simplify)."
I've now updated my code to the following which works, with one caveat (the implementations must have a parameterless constructor, and dependencies must therefore be satisfied by the factory that I'm then using to serve up instances implementing IFoo). I've included the factory registration too for info.
Updated code:
// Get the types that implement IFoo...
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(typeof(IFoo).IsAssignableFrom);
// Register these types and use reflection to instantiate each instance...
foreach (var type in types.Where(x=>x.IsClass))
{
var t = type;
container.Register(() => (IFoo)Activator.CreateInstance(t), t.ToString());
}
// Inject all registered instances of IFoo into IFooFactory when it's instantiated.
// Note that instances of IFoo must have their own dependencies satisfied via the
// factory at runtime before being served by the factory.
container.Register<IFooFactory>(
() => new FooFactory(container.GetAllInstances<IFoo>()));

How to rollback any transaction when doing test with phpUnit in symfony2

I'm testing the controllers using the crawler, but when I'm posting a form that doesn't generate any errors, it save the form in the database.
How can I prevent him to do so without changing the controller, and without testing something else.
Is there best practice about this kinds of test ?
I tried the rollback, but in the ControllerTest there is no more active transactions
You need to write your own test client class extending Symfony\Bundle\FrameworkBundle\Client.
It's because default client doesn't share connection object between requests (so you can't use transactions outside test client). If you extend test client you can handle transaction by your own.
In your client class you need make static connection object, and override method doRequest() to avoid creating new connection object every time but use our static one instead.
It's well described here:
http://alexandre-salome.fr/blog/Symfony2-Isolation-Of-Tests
When you have your own doRequest method all you need is handle transaction, so you wrap handle() method with begin and rollback. Your doRequest method could look sth like that:
protected function doRequest($request)
{
// here you need create your static connection object if it's doesn't exist yet
// and put it into service container as 'doctrine.dbal.default_connection'
(...)
self::$connection->beginTransaction();
$response = $this->kernel->handle($request);
self::$connection->rollback();
(...)
return $response
}
You can read the documentation of PHPUnit for database testing
http://www.phpunit.de/manual/3.6/en/database.html
You will need setup your database and teardown the changes you made.
If you think that the above is too complicated maybe you are interested in make a mockup of your database layer
http://www.phpunit.de/manual/3.6/en/test-doubles.html
Mockup is create a custom object based in the original object where put your own test controls. Probably in this case you are interested in mockup the Entity Manager of Doctrine

How to implement callbacks in Java

I have a class called CommunicationManager which is responsible for communication with server.
It includes methods login() and onLoginResponse(). In case of user login the method login() has to be called and when the server responds the method onLoginResponse() is executed.
What I want to do is to bind actions with user interface. In the GUI class I created an instance of CommunicationManager called mCommunicationManager. From GUI class the login() method is simply called by the line
mCommunicationManager.login();
What I don't know how to do is binding the method from GUI class to onLoginResponse(). For example if the GUI class includes the method notifyUser() which displays the message received from theserver.
I would really appreciate if anyone could show how to bind methods in order to execute the method from GUI class (ex. GUI.notifyUser()) when the instance of the class mCommunicationManager receives the message from the server and the method CommunicationManager.onLoginResponse() is executed.
Thanks!
There's two patterns here I can see you using. One is the publish/subscribe or observer pattern mentioned by Pete. I think this is probably what you want, but seeing as the question mentions binding a method for later execution, I thought I should mention the Command pattern.
The Command pattern is basically a work-around for the fact that java does not treat methods (functions) as first class objects and it's thus impossible to pass them around. Instead, you create an interface that can be passed around and that encapsulates the necessary information about how to call the original method.
So for your example:
interface Command {
public void execute();
}
and you then pass in an instance of this command when you execute the login() function (untested, I always forget how to get anonymous classes right):
final GUI target = this;
command = new Command() {
#Override
public void execute() {
target.notifyUser();
}
};
mCommunicationManager.login(command);
And in the login() function (manager saves reference to command):
public void login() {
command.execute();
}
edit:
I should probably mention that, while this is the general explanation of how it works, in Java there is already some plumbing for this purpose, namely the ActionListener and related classes (actionPerformed() is basically the execute() in Command). These are mostly intended to be used with the AWT and/or Swing classes though, and thus have features specific to that use case.
The idiom used in Java to achieve callback behaviour is Listeners. Construct an interface with methods for the events you want, have a mechanism for registering listener object with the source of the events. When an event occurs, call the corresponding method on each registered listener. This is a common pattern for AWT and Swing events; for a randomly chosen example see FocusListener and the corresponding FocusEvent object.
Note that all the events in Java AWT and Swing inherit ultimately from EventObject, and the convention is to call the listener SomethingListener and the event SomethingEvent. Although you can get away with naming your code whatever you like, it's easier to maintain code which sticks with the conventions of the platform.
As far as I know Java does not support method binding or delegates like C# does.
You may have to implement this via Interfaces (e.g. like Command listener.).
Maybe this website will be helpful:
http://www.javaworld.com/javaworld/javatips/jw-javatip10.html
You can look at the swt-snippets (look at the listeners)
http://www.eclipse.org/swt/snippets/
or you use the runnable class , by overwritting the run method with your 'callback'-code when you create an instance

Resources