How to specify OCL constraint in activity diagram using Eclipse Papyrus? - eclipse

Details
I have an activity diagram for Login section designed in Eclipse Papyrus. Now I have to write OCL constraints for the following conditions:
a username must be string and < 8 characters
a password must be numeric+special chars and > 10 characters
a user can attempt maximum up to 5 times otherwise the system will lock the login
My Effort
I already done this in class diagram like this but don't know how to apply constraints in activity diagram. I have read a lot of articles, watched videos and research papers and checked questions like this, this, this and this but none of them provide a proper answer.
Sample of my activity diagram image

This doesn't seem to have much to do with Activity Diagrams. Your new wording is clear, 5 attempts on one form or one attempt on each of five forms is bad, so User_Account::failedAttempts (rather than login::attempts) is a sensible model feature.
The Constraint is most eaaily defined as an upperbound of 5 on User_Account::failedAttempts. Note that a Constraint defines what is valid not how to react to invalidity. You could more use an invariant to upperbound against a maximumAttempts() computed value. You could inadvisedly use pre/ postconditions on operations or just knit your control operations.
You could sensibly have a User_Account::isLocked() operation whose body is failedAttempts >= maximumAttempts().
The Activity provides the Control for the Model. Presumably it has a lifeline associated with creation/destruction of a login. Presumably it makes use of a DataBase::checkPassword(userName, password) operation that return the User_Account and increments User_Account::failedAttempts as a side-effect. The enforcement of the maximum is therefore in User_Account::checkPassword.
(NB you should not do two stage access for User_Account lookup then password validation to ensure that hackers cannot distinguish, possibly just by response time, whether a failure is due to a bad username or bad password.)
You need to clearly identify what is in the Model; what persists for the duration of your system, perhaps being restored from backup following a system restart. Therefore User_Account must have username and password and failedAttempts properties to define the persistent state.
Conversely what is part of the View/Control can be lost and recreated when another user interaction is initiated. The login form therefore also has username and password properties to represent what is entered on the form and which will be correlated with the Model DataBase by perhaps DataBase::getUserAccount and UserAccount::checkPassword.
I would not pollute the persistent DataBase model with transient login content. If you require recreation of in-progress login attempts across a server failure, I would have a separate ViewDataBase of transient viewed state. If nothing else you would recover the server failure by reactivating the persistent DataBase before reactivating the transient activities.

Related

Onion Architecture - What should an Interface do if has some Data to check after giving structured data (p.ex : an Object) to a Usecase

I have a REST API based on Onion Architecture.
But I have some challenges to apply this way of building a server. Concretely with what should be the behaviour of an Interface if has some data to check before giving structured data to a Usecase.
That is one of my problems:
I have some methods in the Interface that catch info about timers from the request. But I'm facing always the same question. Must I catch all and give to the Usecase and do all checks there, or instead of that, first I have to check if a timer exists in the DB (if i'm updating a timer) and after that do what I need?
This type of checks like Role of who is requesting and what is allowed to do or not, if timers exist, if user exists, if an user already exists and you can't create someone with the same username (I want an unique username restriction) etc, are annoying me because depending on where I'm doing the check, following strictly the Onion Architecture or not, I'm executing more or less code that sometimes is unnecessary.
If I check some things in the Interface, I am avoiding executing code that would be unnecesary. But I'm not following this Architecture correctly, and viceversa.
Any thoughts?

How to model this process using a state diagram?

I am modelling a process using an UML state diagram. Here is some pseudo-code that determines the current state:
function getAccountState(customer) {
if (authorizationRequired(customer)) {
return State.AUTHORIZATION_REQUIRED
}
if (updateRequired(customer)) {
return State.UPDATE_REQUIRED
}
return State.DRAFT
}
The closest I got was this diagram:
However, I think it is somewhat strange that each transition is contained twice. The order matters though which means, the authorization-check should always come first.
How would one model this process?
EDIT:
The background behind this process is a REST service. The account is modeled as a resource and can go through various states. Any time the resource is requested, the service performs the checks in the order described by the pseudo code above to generate an according representation. Depending on the answer, it includes either:
a link to authorize the account if the account requires authorization
a link to update the profile if an update is needed (this however can only happen once the account is authorized or does not have to be authorized)
a link to finalize the account if the profile is up-to-date (either because it had to be updated and was updated by the client or it never had to be updated in the first place)
The code above is just an example though. The service could also utilize a database field storing the "state", although this is an anti-pattern isn't? It is more feasible to "derive" the current state by applying the business rules on the stored data instead of (redundantly) storing the state in a separate field. That is what the pseudo code should indicate.
According to your edit, I'd come up with the following approach:
You will reach the Draft state through (optional) authorization and updating. If they fail, the state machine is reset.
I would suggest one remark about the point "it is somewhat strange that each transition is contained twice", I understood that from one state you can have several transitions triggered by the same event but in this case, transitions have different guards. As I remember, the notation is evt[guard]. Hope this help.

CQRS - When a command cannot resolve to a domain

I'm trying to wrap my head around CQRS. I'm drawing from the code example provided here. Please be gentle I'm very new to this pattern.
I'm looking at a logon scenario. I like this scenario because it's not really demonstrated in any examples i've read. In this case I do not know what the aggregate id of the user is or even if there is one as all I start with is a username and password.
In the fohjin example events are always fired from the domain (if needed) and the command handler calls some method on the domain. However if a user logon is invalid I have no domain to call anything on. Also most, if not all of the base Command/Event classes defined in the fohjin project pass around an aggregate id.
In the case of the event LogonFailure I may want to update a LogonAudit report.
So my question is: how to handle commands that do not resolve to a particular aggregate? How would that flow?
public void Execute(UserLogonCommand command)
{
var user = null;//user looked up by username somehow, should i query the report database to resolve the username to an id?
if (user == null || user.Password != command.Password)
;//What to do here? I want to raise an event somehow that doesn't target a specific user
else
user.LogonSuccessful();
}
You should take into account that it most cases CQRS and DDD is suitable just for some parts of the system. It is very uncommon to model entire system with CQRS concepts - it fits best to the parts with complex business domain and I wouldn't call logging user in a particularly complex business scenario. In fact, in most cases it's not business-related at all. The actual business domain starts when user is already identified.
Another thing to remember is that due to eventual consistency it is extremely beneficial to check as much as we can using only query-side, without event creating any commands/events.
Assuming however, that the information about successful / failed user log-ins is meaningful I'd model your scenario with following steps
User provides name and password
Name/password is validated against some kind of query database
When provided credentials are valid RegisterValidUserCommand(userId) is executed which results in proper event
If provided credentials are not valid
RegisterInvalidCredentialsCommand(providedUserName) is executed which results in proper event
The point is that checking user credentials is not necessarily part of business domain.
That said, there is another related concept, in which not every command or event needs to be business - related, thus it is possible to handle events that don't need aggregates to be loaded.
For example you want to change data that is informational-only and in no way affects business concepts of your system, like information about person's sex (once again, assuming that it has no business meaning).
In that case when you handle SetPersonSexCommand there's actually no need to load aggregate as that information doesn't even have to be located on entities, instead you create PersonSexSetEvent, register it, and publish so the query side could project it to the screen/raport.

Creation Concurrency with CQRS and EventStore

Baseline info:
I'm using an external OAuth provider for login. If the user logs into the external OAuth, they are OK to enter my system. However this user may not yet exist in my system. It's not really a technology issue, but I'm using JOliver EventStore for what it's worth.
Logic:
I'm not given a guid for new users. I just have an email address.
I check my read model before sending a command, if the user email
exists, I issue a Login command with the ID, if not I issue a
CreateUser command with a generated ID. My issue is in the case of a new user.
A save occurs in the event store with the new ID.
Issue:
Assume two create commands are somehow issued before the read model is updated due to browser refresh or some other anomaly that occurs before consistency with the read model is achieved. That's OK that's not my problem.
What Happens:
Because the new ID is a Guid comb, there's no chance the event store will know that these two CreateUser commands represent the same user. By the time they get to the read model, the read model will know (because they have the same email) and can merge the two records or take some other compensating action. But now my read model is out of sync with the event store which still thinks these are two separate entities.
Perhaps it doesn't matter because:
Replaying the events will have the same effect on the read model
so that should be OK.
Because both commands are duplicate "Create" commands, they should contain identical information, so it's not like I'm losing anything in the event store.
Can anybody illuminate how they handled similar issues? If some compensating action needs to occur does the read model service issue some kind of compensation command when it realizes it's got a duplicate entry? Is there a simpler methodology I'm not considering?
You're very close to what I'd consider a proper possible solution. The scenario, if I may summarize, is somewhat like this:
Perform the OAuth-entication.
Using the read model decide between a recurring visitor and a new visitor, based on the email address.
In case of a new visitor, send a RegisterNewVisitor command message that gets handled and stored in the eventstore.
Assume there is some concurrency going on that, for the same email address, causes two RegisterNewVisitor messages, each containing what the system thinks is the key associated with the email address. These keys (guids) are different.
Detect this duplicate key issue in the read model and merge both read model records into one record.
Now instead of merging the records in the read model, why not send a ResolveDuplicateVisitorEmailAddress { Key1, Key2 } towards your domain model, leaving it up to the domain model (the codified form of the business decision to be taken) to resolve this issue. You could even have a dedicated read model to deal with these kind of issues, the other read model will just get a kind of DuplicateVisitorEmailAddressResolved event, and project it into the proper records.
Word of warning: You've asked a technical question and I gave you a technical, possible solution. In general, I would not apply this technique unless I had some business indicator that this is worth investing in (what's the frequency of a user logging in concurrently for the first time - maybe solving it this way is just a way of ignoring the root cause (flakey OAuth, no register new visitor process in place, etc)). There are other technical solutions to this problem but I wanted to give you the one closest to what you already have in place. They range from registering new visitors sequentially to keeping an in-memory projection of the visitors not yet in the read model.

How do I pretend duplicate values in my read database with CQRS

Say that I have a User table in my ReadDatabase (use SQL Server). In a regulare read/write database I can put like a index on the table to make sure that 2 users aren't addedd to the table with the same emailadress.
So if I try to add a user with a emailadress that already exist in my table for a diffrent user, the sql server will throw an exception back.
In Cqrs I can't do that since if I decouple the write to my readdatabas from the domain model, by puting it on an asyncronus queue I wont get the exception thrown back to me, and I will return "OK" to the UI and the user will think that he is added to the database, when infact he will never be added to the read database.
I can do a search in the read database checking if there is a user already in my database with the emailadress, and if there is one, then thru an exception back to the UI. But if they press the save button the same time, I will do 2 checks to the database and see that there isn't any user in the database with the emailadress, I send back that it's okay. Put it on my queue and later it will fail (by hitting the unique identifier).
Am I suppose to load all users from my EventSource (it's a SQL Server) and then do the check on that collection, to see if I have a User that already has this emailadress. That sounds a bit crazy too me...
How have you people solved it?
The way I can see is to not using an asyncronized queue, but use a syncronized one but that will affect perfomance really bad, specially when you have many "read storages" to write to...
Need some help here...
Searching for CQRS Set Based Validation will give you solutions to this issue.
Greg Young posted about the business impact of embracing eventual consistency http://codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/
Jérémie Chassaing posted about discovering missing aggregate roots in the domain http://thinkbeforecoding.com/post/2009/10/28/Uniqueness-validation-in-CQRS-Architecture
Related stack overflow questions:
How to handle set based consistency validation in CQRS?
CQRS Validation & uniqueness