First make an actual aggregate (likely they don't exist) make it using
events, but have handlers writing back to the database.
As part of this I will snapshot the aggregate (assuming I can't build
up a history for it) likely with an originating "create" event.
I will save all future events into a log.
At this point I have all the benefits of event sourcing (I have an
event log) but still have relational database.
I will at this point talk about the cost of keeping the relational
database and what benefits it provides as often it is none :) but the
reasons for getting rid of it are usually cost based.
Make sense?
Greg
--
Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer
de votre attention
Domain Service.
Nuno
FWIW, I'm working through something quite similar too right now.
Our external system uses OpenJPA and I've added a listener to the
persistence, from there I'm able to query the Entity about which
fields are dirty. I then collect the class name, PK and dirty fields
and commit a AnnounceChangesCommand() into my command bus within the
scope of the other system's transaction.
From there I have a command handler which can map classname+PK to
AR+UUID in my system, and depending on which fields have changed, I
generate appropriate events and commit them onto my event bus.
The events populate my read-side and build my event store.
JAmes
// I'm sorry if this hijacks thread.
What if we are not evolving a single system, but need to continuously
integrate 2 distinct systems A and B (which tends to happen
embarrassingly frequently these days)?
System A is under our full control and features full event sourcing.
System B does not have event sourcing and is outside of our control.
At most we can query it for "what records were
created/updated/deleted" since time X.
Let's say B is some proprietary CRM that sales department just loves
using. Whenever they create a new lead, we need to bring it into the
system A.
If manager or autopilot modify this contact within system A, changes
should be synced back to B.
Now, if we assume that deciphering user intent (diffing) CRUD changes
from B into events in A, is not a problem, how would you approach the
integration?
Logically, if we treat A as the single source of truth (which it
should be, since it has the event store which is more complete than
state DB), then B should be treated just like some remote UI client,
that sends commands (which are decyphered from the CRUD changes and
could be rejected) and gets synced back by overwriting it's state with
the state built from the events.
Am I even remotely close to the right track from the logical
perspective? How would you approach the situation?
Best regards,
Rinat
Let's say we are talking about situation where it is impossible
(unfeasible due to the political reasons or resource constraints of
the project) to be messing with the internals of B (i.e: too complex,
closed source and black-box behavior, different platform, CTO does not
want to allocate resources in dealing with B internals etc).
All we can do is to poll it for diff changes and push CRUD commands
back. So, essentially, there is no clear way to message from B to A.
We can only query for changes and write our changes back. Any conflict
resolution should, obviously happen in A.
Any ideas?
Best regards,
Rinat
Sent from my iPhone
We share the same challenge as you here all the time. The company I work for decided to off load some non core business processes to Sales Force. Don't know the precise details of how they are doing (different project) but I'll try to have a look.
Last time I head they do bulk periodical updates from system A to system B through some kind of DTS. A mess IMHO but again not my decision. Sales force for instance doesn't publish events.
Whatever is the solution we need to dive into understanding the business processes that system A and system B automate and business concepts used. Through understating process we can capture how the business clock works in each domain (domain time). Only then we understand how synchronize the domain clocks of system A and B can be synchronized and viable.
I think if you are striving for an automated generic solution, you will fail and the integration processes will not scale well.
> How do you assemble changes for the entity-b? Should "anti-corruption" layer subscribe to all events, filter out ones that it produced and use the rest to figure out CRUD deltas for the last known state of entity-b? Or do something else?
"As the domain luke"
Hope it helps,
Nuno
PS: Sorry for being so abstract. Maybe you can share more detail about the domains A and B automate.
Just trying to get my head around and formalize approaches.
I'm not trying to find a generic automated solution. Such thing is
unfortunately impossible (or prohibitively expensive) and I have been
bitten hard enough in the past to learn the lesson))
I'm just trying to arrive at the methodology that describes the logic
how these changes should be derived and handled. Once you have the
logic stable, architectures and implementations are simple to build
around, tailoring to each specific case.
So, for example, although there is a logic (rather a set of additional
constraints to follow) for building almost-infinitely scalable
solutions with CQRS/DDD/ES, or handling versioning and concurrent
changes, I can't get the logic for integrating state-based and event
based solutions. It's as if there were absolutely no generic
rules/guidelines to follow and you had to learn the domain to an end
and then come up with completely custom solution (without any
similarities between solutions in every case).
Examples of CQRS-A and External-B are, for example.
B: Web-based CRM used by the Sales department for historical reasons
A: Digital Nervous System of the company, that handles customers,
billing and subscriptions.
We need to detect changes in B (i.e.: changing customer details,
adding additional contacts to the company) and propagate into A,
applying all changes in the reverse direction as well.
Another one:
B: Closed source task management solution with a certain and unique value
B: Task management solution on another platform with another certain
and unique value
A: Integration platform, that detects changes in these systems, and
syncs them, also keeping track of the history, adding additional
notifications etc.
In each case I'm assuming that the challenge of figuring out the
answer to "Given state 1 and state 2, what were the business changes?"
is not the problem (or rather it is a problem that could and would be
solved by the domain).
I'm sorry if this sounds confusing; just can't seem to find better words.
Best regards,
Rinat
> I can't get the logic for integrating state-based and event
> based solutions.
I think you can though Aggregates.
What you loose from passing from one to another is the domain events that provoke the state change of either A (only preserves the latest state) or B (preserves all state changes).
So if we want to synch between both systems all we can do is compare the least common denominator which is the latest state of an Aggregates (snapshot).
So we need to stop thinking of events and look at the latest state as usual. The Aggregate state.
> It's as if there were absolutely no generic
> rules/guidelines to follow and you had to learn the domain to an end
> and then come up with completely custom solution (without any
> similarities between solutions in every case).
Within this, it is of advantage to consider the latest state as a value object that can be transacted between A and B.
But for that you need to find what is in B that is of value to A and vice versa.
For that matter I would advise studying what is of value to A in B. And what is of value to B in A. Within the scope of each business feature of A then B.
The result is the information that need to be compared, when,and in synch.
Architecturally the synch rules are then implemented in the Anti-corruption Layer. You can use scripts if events cannot be passed on from one to another. Or if they can, probably you can use Sagas :)
Does this help,
Nuno
If the term business feature does not ring many technical bells. what about Slice (as of SOA slice)?.
Nuno
Yes, System A in all these situation captures events for the purpose
of added business value as well as the scalability and collaboration.
// NB: figuring intentions out of diffs is never an easy task, but
it's something doable (with a certain degree of precision).
So I'm ending with something like AntiCorruption Layer + Domain
Service, as Nuno have kindly mentioned earlier.
Basically this IntegrationProcess is a process (overgrown saga) that
keeps the last known state of the system B and is capable of figuring
out "what has changed" and sending this into system A as commands,
that make sense in our CQRS/ES/DDD world. All id mappings and logical
conversions happen within this process and stay there.
Sync happens on a schedule.
Getting data from B to A is the easy part. Getting out changes back to
B is still where it is fuzzy.
Although this specific project is not a real one (it does not have any
specific goals aside from practicing CQRS/DDD/ES, integration with the
legacy systems and scalability in the cloud), we did some
brainstorming today. So for getting the data out to B, it seems the
approach would be to let IntegrationProcess track all domain events
that originated within the system A (these events will be mixed with
the domain events originated from the changes that came in through the
same sync process). Then, based on the changes it will build snapshots
and compose diffs between two syncs (the "magic happens here" part
that is still unclear). These diffs will be sent back to the System B
(we can't send commands, we can just send these diffs, similar to the
ones we've got).
We'll see if the approach justifies its right to live after being
applied to the working system.
Best regards,
Rinat