Command Pattern: Client and Invoker - command-pattern

In the command pattern:
Why shouldn't the client participant be the same class as the invoker participant? Is there possible scenarios when the client participant and the invoker participant can be the same class?

Biggest reason is that it violates the single responsiblity principle. The Client participant and Invoker particpant both have individual responsibilties and a change to one will affect the other.

1) Main responsibility for Client is to proper instanciation of Invoker, Receiver and Command objects and then initiate execution procedure in appropriate place and time.
It could, for example, be something like this
class Client {
...
invoker.executeCommand()
...
}
2) Main responsibility for Invoker is to invoke one or more command-methods of Command Object in particular order.
For example,
class Invoker {
...
command.command1();
command.command2();
command.command3();
...
}
Let's consider, for example, java.awt.event.KeyListener class. It has three methods that is invoked in the following order:
keyPressed(KeyEvent e)
keyTyped(KeyEvent e)
keyReleased(KeyEvent e)
Invoker class for this listener could be:
class KeyInvocation {
KeyListener listener;
void invokeKey(EventObject e) {
listener.keyPressed(e);
listener.keyTyped(e);
listener.keyReleased(e);
}
}
Meantime Client class should proper instanciate EventObject, KeyListener and KeyInvocation and then execute in proper place and time invokeKey method.
Of course Invoker is a additional layer of Command pattern.
In simpler case of Command pattern we can skip Invoker class at all and do all the work in Client one.

So let's take an example of a text editor. When you open an application the application is the client and it will store various receivers and command in their invokers. eg. It will add pasteCommand to paste menu item where receiver is the document. It will add openCommand to open menu item where receiver is the application itself.
This exactly answers your question how invoker and client can be different

Related

guava eventbus post after transaction/commit

I am currently playing around with guava's eventbus in spring and while the general functionality is working fine so far i came across the following problem:
When a user want's to change data on a "Line" entity this is handled as usual in a backend service. In this service the data will be persisted via JPA first and after that I create a "NotificationEvent" with a reference to the changed entity. Via the EventBus I send the reference of the line to all subscribers.
public void notifyUI(String lineId) {
EventBus eventBus = getClientEventBus();
eventBus.post(new LineNotificationEvent(lineId));
}
the eventbus itself is created simply using new EventBus() in the background.
now in this case my subscribers are on the frontend side, outside of the #Transactional realm. so when I change my data, post the event and let the subscribers get all necessary updates from the database the actual transaction is not committed yet, which makes the subscribers fetch the old data.
the only quick fix i can think of is handling it asynchronously and wait for a second or two. But is there another way to post the events using guava AFTER the transaction has been committed?
I don't think guava is "aware" of spring at all, and in particular not with its "#Transactional" stuff.
So you need a creative solution here. One solution I can think about is to move this code to the place where you're sure that the transaction has finished.
One way to achieve that is using TransactionSyncrhonizationManager:
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){
void afterCommit(){
// do what you want to do after commit
// in this case call the notifyUI method
}
});
Note, that if the transaction fails (rolls back) the method won't be called, in this case you'll probably need afterCompletion method. See documentation
Another possible approach is refactoring your application to something like this:
#Service
public class NonTransactionalService {
#Autowired
private ExistingService existing;
public void entryPoint() {
String lineId = existing.invokeInTransaction(...);
// now you know for sure that the transaction has been committed
notifyUI(lineId);
}
}
#Service
public class ExistingService {
#Transactional
public String invokeInTransaction(...) {
// do your stuff that you've done before
}
}
One last thing I would like to mention here, is that Spring itself provides an events mechanism, that you might use instead of guava's one.
See this tutorial for example

DDD: Where to raise "created" domain event

I struggle to find and implement the best practise for the following problem: where is the best location to raise create domain event (the event that notifies for the creation of an aggregate). For example if we have Order aggregate in our bounded context we would like to notifie all interested parties when order is create. The event could be OrderCreatedEvent.
What I tried in first place is to raise this event in the constructor (I have a collection of domain events in each aggregate). This way it is okay only when we create the order. Because when we would like to do anything with this aggregate in the future we are going to create new instance of it through the constructor. Then OrderCreatedEvent will be raised again but it is not true.
However, I thought it would be okey to raise the event in the application layer but it is an anti-pattern (the domain events should live only in the domain). Maybe to have a method Create that will just add the OrderCreatedEvent to its domain events list and call it in the application layer when order is created is an option.
Interesting fact I found on the internet is that it is an anti-pattern to raise domain events in the contructor which means the last described option (to have Create method) would be the best approach.
I am using Spring Boot for the application and MapStruct for the mapper that maps the database/repository Entity to the domain model aggregate. Also, tried to find a way to create a mapper that is going to skip the contructor of the target class but as all properties of the Order aggregate are private seems impossible.
Usually constructor are used only to make assignations on object's fields. This is not the right place to trigger behaviours, especially when they throw exceptions or have side effects
DDD theorists (from Eric Evans onwards) suggest implementing factories for aggregates creation. A factory method, for example, can invoke aggregate constructor (and wire up the aggregate with child domain objects as well) and also register an event.
Publishing events from the application layer is not an anti-pattern per se. Application services can depend from the domain events publisher, the important thing is that it's not application layer to decide which event to send
To summarize, with a stack like Java Spring Boot and domain events support, your code could look like
public class MyAggregate extends AbstractAggregateRoot {
public static MyAggregate create() {
MyAggregate created = new MyAggregate();
created.registerEvent(new MyAggregateCreated());
return created;
}
}
public class MyApplicationService {
#Autowired private MyAggregateRepository repository;
public void createAnAggregate() {
repository.save(MyAggregate.create());
}
}
notice that event publishing happens automagically after calling repository.save(). The downside here is that, when you use db-generated identifiers, aggregate id is not avaliable in the event payload since it's associated after persisting the aggregate. If i will change the application service code like that:
public class MyApplicationService {
#Autowired private MyAggregateRepository repository;
#Autowired private ApplicationEventPublisher publisher;
public void createAnAggregate() {
repository.save(MyAggregate.create()).domainEvents().forEach(evt -> {
publisher.publish(evt);
});
}
}
Application layer is in charge to decide what to do to fulfill this workflow (create an aggregate, persist it and send some event) but all the steps happen transparently. I can add a new property to the aggregate root, change DBMS or change event contract, this won't change these lines of code. Application layer decides what to do and domain layer decides how to do it. Factories are part of the domain layer, events are a transient part of the aggregate state and the publishing part is transparent from domain standpoint
Check out this question!
Is it safe to publish Domain Event before persisting the Aggregate?.
However, I thought it would be okey to raise the event in the application layer but it is an anti-pattern (the domain events should live only in the domain). - Domain events live in Domain layer, but Application layer references Domain layer and can easily emit domain events.

How can I access the lambda execution context from within a Quarkus REST API?

A regular Lambda handler has it, but in the Quarkus generated JAX-RS handler I cannot find a way to access it. I assume there should be a way to inject it or something... Why I'm asking? I would like to read the lambda execution ID to pass it back, so I can check when this particular execution has ended - without the extra work of creating extra resources (including step functions) or database flags.
It depends on which context you want and which dependency / API Gateway you use.
For lambda context you can use:
#Path("/myresource")
public class MyResource {
#GET
public String ctx(#Context com.amazonaws.services.lambda.runtime.Context ctx) { }
}
See: https://quarkus.io/guides/amazon-lambda-http#injectable-aws-context-variables

EntityFrameworkCore - Diagnosing "The connection was not closed. The connection's current state is open."

We seem to have done something to introduce some kind of threading issue into our app. It's a dotnet core 1.1.2 application, using EntityFrameworkCore. Intermittently, but reproducably, we will get one of these errors:
System.InvalidOperationException: 'The connection was not closed. The connection's current state is open.' exception when running an EF query.
or
System.InvalidCastException: 'Unable to cast object of type 'System.Data.ProviderBase.DbConnectionClosedConnecting' to type 'System.Data.SqlClient.SqlInternalConnectionTds'.'
or
System.ObjectDisposedException: 'Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.'
This can happen at almost any point in the app, but this method seems to be the most frequent culprit (this does get called somewhat frequently):
public class WidgetConfigurationRepository : IWidgetConfigurationRepository
{
public WidgetConfigurationRepository(LocalContext dataContext)
{
Context = dataContext ?? throw new ArgumentNullException(nameof(dataContext));
}
private LocalContext _context { get; private set; }
public async Task<WidgetConfiguration> LoadConfigurationAsync(Guid widgetId)
{
return await _context.WidgetConfigurations
.Include(x => x.Options)
.FirstOrDefaultAsync(x => x.WidgetId.Equals(widgetId));
}
...
}
the repository is created via the Core DI container, and is injected at runtime:
services.AddScoped<IWidgetConfigurationRepository, WidgetConfigurationRepository>();
The Repository and the LocalContext are both registered as Scoped, and there are no Singleton accessors of the LocalContext.
Walking through the stack trace (and the parallel stacks) shows that every async method is awaited, and I have gone through replacing the interfaces in the application with the implementations, to hopefully try to find any async without await.
The LocalContext itself is created via a LocalDbContextFactory that is also registered as Scoped. It reads data from a central data context, checks some data and then instantiates a new instance of the LocalContext. This is only happening once per request, as expected.
Ultimately, I'm looking for some help working out what could be causing this, our app is now fairly large and I'm not sure I can provide enough code snippets to help.
At the moment, I think my best option is to write a Roslyn analyzer to go through all the methods that return Task or Task<T> and check that something happens with the return object, but I'm wondering if there is something easier that I may have missed.
There is this related question: EF. The connection was not closed. The connection's current state is connecting
with the
Re-check that IUserService is registered with "scope" lifetime, and all it dependencies (userManager, dbContext) too
Do not use IServiceProvider you obtained during app startup for scope-bases services resolution - it is NOT related to current request scope and return instances from "some other universe". Use HttpContext.RequestServices for service resolution.
Check that your are "awaiting" all async methods. If you start second request while still executing first one - you may possibly "catch" dbContext during "connecting" stage.
Your JwtMessageHandler instance is one/single per app. So don't use it's property for storing _userService (remove private IUserService _userService). Instead, use local variable inside OnMessageReceived (var _userService = ...).
As far as I can tell, we are not being caught by any of these, almost all of our services are Scoped or Transient.
We use ServiceProvider.GetService<>() during the app startup, to resolve the database to run Migrations on, but not beyond that.
I think it's possible that there is an async without an await, but I don't seem to be able to find it, and we aren't getting compiler warnings for it.

A way to work in Spring Integration (/Dsl) with DestinationResolvers

Can I configure a single JmsMessageDrivenChannelAdapter so it is able to work with different destinations, via DestinationResolvers or such? I'd like to provide the destination logic via the IntegrationFlows builder, so I can reuse the component (I don't need to create one adapter per topic), or centralize all destinations sources/decision rules in a single class
You can do it like this:
IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory())
.destination("DUMMY")
.configureListenerContainer(c ->
c.destinationResolver((session, s, b) ->
YOUR LOGIC FOR DYNAMIC DESTINATION RESOLUTION)))
You need that "DUMMY" destination configuration to mock the container state:
protected void validateConfiguration() {
if (this.destination == null) {
throw new IllegalArgumentException("Property 'destination' or 'destinationName' is required");
}
}
OTOH I'm not sure that it is going to work properly anyway.
The container starts a JMS Consumer based on the destination (even if you provide it via the custom DestinationResolver) and it can't be changed until the container stop.
You can consider to use Jms.inboundAdapter() though, which is pollable, but based on the JmsTemplate.receiveSelected(). That way you can change a destination on each receive() invocation from the poller.
You will need dummy destinationName configuration there anyway. Otherwise it doesn't go to the getDestinationResolver().

Resources