I have read all about the different variants of Uuid, and I have watched talks by Martin Fowler on the topic of Event Sourcing, so I am of the thinking I should be creating Uuids that are going to be the same every time the object is created.
Named UUIDs are great for this.
How do I even tackle this with user-generated data? The reason is that if I want to mimic a system on testing to fix a live bug, shouldn't I create the exact same IDs?
Same game as above - the point to using named uuid is that you are generating your identifiers deterministically, which means that you can reproduce them from the same inputs.
For the most part, you don't ever really care what the identifier is, just that it is determined. So if your user generated data includes an identifier, then that's fine -- when testing your system, you can reproduce the user's request with the same identifier that the client provided. That identifier can be fixed or random, as necessary.
If you get user requests without an identifier, then you'll want to add one in. You may be able to do so by simply hashing the data provided by the client; but if that can be duplicated then you'll need to introduce some additional element to ensure that the identifiers are unique.
Would you suggest that the client (written in the same language) would just use the same Uuid generating code?
Deterministic code is always much easier to test than not, so where it makes sense, sure. But from the point of view of the server, I don't really care where the ids generated by the client come from.
Also, how would you suggest using the client inputs? A sha1 of all the data for example?
Maybe, but not necessarily. Give some thought to when you want identifiers to collide.
For instance, if I'm a client trying to send a command message, then I'm probably going to give that message an identifier that is unique, so that the message will collide with a duplicate copy of itself.
If the message is intended to create a new entity, then it may be an advantage to have that identifier naturally collide with an entity created by a different client. In that case, there are two cases you may wish to handle -- the two clients try to create the entity with the same state, the two clients try to create the entity with different states.
If you and I both try to create the "same" customer, but one of us makes a mistake spelling the street address, then we probably don't want two copies of the customer in the model, but rather one customer and maybe some handling to get the address confirmed.