how to invoke an operation with the data we get after processing - workflow

Hello guys I'm looking for creating an work flow where it will do some processing and will fetch some persons. I need to enforce each person by invoking an extension which takes a person entity as in put.
Any suggestions or pointers will be deeply appreciated.

I going to to assume you want to use an ITIM operation to do this, and you are not going to use an operation tied to an activity (e.g. person/account modify, restore, suspend, add, delete, etc.).
So for example, if you want to create an operation that fetches all users where their department=sales and you want to make a change to those persons (e.g. change all their phone numbers to be 800-555-1212) then you could use a lifecycle rule coupled with an operation.
First create an operation. I would suggest creating the operation at the entity type level of Person unless you need to specifically only allow this operation to work on one person type. Once you get into the operation diagram java applet, click the Properties button and change the operation type to Non Static.
Now, do your coding and flow in the operation. Your person will be coming in as the relevant data object Entity. So make your changes in a script node, then send it through a modify person extension, and finally a policy enforcement extension. I recommend the policy enforcement extension because if you are using provisioning policies then you want any accounts to be updated when you update the extension.
Save your operation, and create a lifecycle at the same level (either at the global Person at the entity level of a specific Person type). Set the operation for the lifecycle to the same operation you just created. On the event page, set your filter to be what you are wanting the operation to apply to (e.g. (department=sales)). You can set a schedule on the lifecycle to automate it, or you can simply save it and run the lifecycle manually by selecting it and clicking the Run button.
Check within IBM's InfoCenter pages for more information on all the workflow extensions that are available out of the box, as well as all of the javascript functions that are available.

Related

Odoo - Why odoo store data of TransientModel like res.config.settings into ir.config_parameter?

res.config.settings model is TransientModel and TransientModel are designed to be stored temporary data, After periodically time it will remove data from the database. For saving those settings we have to implement set_param and get_param method of ir.config_parameter.
So, Here I want to know why odoo used ir.config_parameter to store those setting values. Why we can't make res.config.settings as Model instead of TransientModel and store data into that model.
I'm not odoo so I cannot answer for them, but I can explain you why I consider this logic.
In odoo, you have the traditional MVC paradigm, but there are places where you don't really have a model: you just want a view and a controller. This is the case for wizards in odoo. Wizards are just helper dialogs to let the user perform hard tasks in an easier way.
However, if they have no model, how to define the data they use? Where to attach controller logic? It would be very hard and would request a whole new programming paradigm inside odoo, so they took an easier solution: transient models.
So in odoo a transient model is basically a wizard. What happens when you open a wizard?
Odoo obtains the view definition.
Calls the controller to obtain default data (default_get()).
Draws a form for you, but there's no record yet in the database.
You can alter the form as usual, and the normal compute and onchange methods work out of the box.
You hit some button in the wizard, to perform any action.
Odoo creates a new record in the wizard table.
The method associated with that button is executed in the server.
The next time you open the wizard, it follows the same procedure. As you can imagine, this creates a lot of records, because a wizard record is always used only once, so there's a cron job that deletes that garbage every now and then. That's why they're called "transient".
The purpose of ir.config_parameter is to store and retrieve database-wide configuration. 1 record = 1 parameter. You can create parameters without using a wizard. These are not transient, so it's the proper place to store parameters.
The purpose of res.config.settings is to help you configure the system, but that's more than just storing system parameters: it involves configuring auth methods, installing modules, giving you shortcuts for mail gateways configuration, installing a theme in each website, choosing a chart of accounts for each company, etc.
It would make no sense to merge all of that in ir.config_parameter.

Event-Sourcing how to change business rules

My application use cqrs and event sourcing. It's already in production.
Now i must add a business rules. My business rules are in my aggregate root UserAggregate.
My commands :
public class CallUserForMarketingPlanCommand
{
public Guid UserId {get;set;}
public DateTime CallDate {get;set;}
public Guid PlanId {get;set;}
}
public class AcceptMarketingPlanCommand
{
public Guid UserId {get;set;}
public Date AswerDate {get;set;}
public Guid PlanId {get;set;}
}
... the same thing for RefuseMarketingPlanCommand
these commands are applied on my aggregate root which generate events stored in event store
Now if 50 days after the call, the user do not give answer, the user must be recalled by operator. To do this, i think generate event UserDoNotRepliedInDelayEvent and use it to project to a read model with recall informations.
My solution is to create a deferred command (from UserCalledForMarketingPlanEvent handler) CheckUserAnswerCommand which check the call date and generate UserDoNotRepliedInDelayEvent if necessary across the aggregate. Ok.
My problem is how to deffered this command on users already in my event store (before this change) ?
EDIT :
Without considering deferred message, how to change business rules (or a business rules parameter) affecting the state of an aggregate. Simple example :
Disable account if two payments are not permformed.
this rule come with the first deployement. Ok, now there are 1000 accounts disabled. The boss change the rule because the business is impacted, and want disable account if 5 payments are not performed.
How to enable account having less than 5 payments not performed ?
Thanks for your help.
Now if 50 days after the call, the user do not give answer, the user must be recalled by operator. To do this, i think generate event UserDoNotRepliedInDelayEvent and use it to project to a read model with recall informations.
If I undestood your question correctly, the main point here, is that the user "not replying" in time is not an action (command) of your domain, quite the contrary, it is the absence of an action. So in this scenario, I don't think you need an event at all.
You simply need a read model which will register all sent invitations and their statuses (whether they're replied, their reply dates and how long did they stand unanswered). Then, you can check this read model for unanswered invitations that exceed your deadline of 50 days (which should be simple enough at this point).
So, up to this point, no new events are generated in your "Invitations" event store. You're simply interpreting the store into a specific read model that will answer you a question you have (which invitations were not answered).
From this point, it depends on your architecture.
You might want a recurring process to check this read model for invitations that exceed your deadline, having those specific invitations trigger a "InvitationExpiredEvent" or something to notify the interested parties (those who will resend them, for instance)
Or you simply might want a more passive approach, not needing an extra event, simply reading this Read Model when appropriate (on the GUI, maybe) and listing the expired invitations.
This will then fix itself... since you can generate the read model retroactively (finding users from any given point in the that never answered their invitations) and put them through the re-invitation pipeline.
Without considering deferred message, how to change business rules (or a business rules parameter) affecting the state of an aggregate. Simple example :
Disable account if two payments are not permformed.
this rule come with the first deployement. Ok, now there are 1000 accounts disabled. The boss change the rule because the business is impacted, and want disable account if 5 payments are not performed.
How to enable account having less than 5 payments not performed ?
This part of your question is more confusing. From what I understood, you once had a rule that stated "Accounts with two or more expired payments should be inactivated" and you want to change this rule to "Accounts with five or more expired payments should be inactivated". If that's the case, you have to deal with this on multiple levels...
First, you must first implement the new rule on your command model, the same way it always have been but with the updated parameter.
Second, you cannot retroactively reactivated accounts with 2,3,4 expired payments by ignoring their "deactivation events". From your event store point of view, this happened and you must abide by the rules that an event store is a "push only" storage. So, you must use compensating events to reactivate them after the rule change.
So, if you took care of the first topic (and your domain is up and running with the new rule) and since you can't take a shortcut because of the second topic, one of your easier options is to simply develop a one-shot operation that will find accounts with 2,3,4 expired payments that are currently disabled and append to their event stores a reactivation event. At this point you will have to regenerate any affected read models if your architecture doesn't do this automatically.
That way, the next time commands are executed against these accounts, their event stores will reflect the fact that they have been reactivated and thus are currently active.
From an event store point of view... each of these accounts will have something like this on their event streams:
... > Payment Expired > Account Disabled > (maybe other stuff happened) > Account Re-Enabled
So your event store will be a pretty accurate representation of your business scenario... once you chose to disable accounts with only 2 expired payments, so a certain account was disabled by that... later you changed your mind, and even without paying their debts, these accounts were re-enabled.
EDIT:
In fact, i think the problem can be summarized by "how to integrate retroactive rules in event sourced system"
If that's the case, than the answer will be more focused on the lines of "there shouldn't be retroactive actions in an event-sourced domain".
As I said in my original answer, an event stream should be a "push-only" storage and that's mainly because only the exact order of events, as they happened, can guarantee the integrity of your rules as they were when those events happened. In that sense, an event storage is less flexible than a traditional one as it will be way more sensitive to external interference and that will sometimes be a pain (were used to meddling with the data sources directly to fix stuff).
However, we should really try to keep the rule and acknowledge that whatever happened, happened and can't be changed. What you can do, is add, to the end of event stream "compensation events" that is, new events that will register a change of state at a given time to reflect your rules-changing. And then you will need a one-shot process to go through your entities and decide which of them are eligible for such a compensating event.
Now, of course, rules are meant to be broken when needed and with enough consideration, you can go wild into the event store. Just know the risks. If you choose to go "full time machine mode" into the event store, the main risks you will face (and should guard against) are:
Entities going into invalid states in their lifetime. It doesn't matter the entity "ends" the event stream in a valid state. You must validate it never enters an invalid state as that is a prerequisite of event streams. So, for each entity affected by your editing, you will need to evaluate its validity step by step through the new event stream.
Mismatches between source code and event stream. This is a little trickier. But one of the maneuvers you can pull with an event sourced system is rollback your source code repository to a given date and "discard" events from that date forward. That way, you can re-execute actions as they would have happened in the past. If you edit past events though, you might face situations where the recorded events don't match what would have happened in the past based on source code. That might be critical and extremely misleading in the future. You should monitor that.
If your architecture integrates different contexts/domains/microservices, that might also need further evaluation. Say context-A issued a cross-boundary message to context-B because of a given state of an entity. Moving forward, you change the entity state by meddling with the event stream. Now there's a chance these contexts might be left inconsistent between them as context-B believes that entity had a state it no longer has. This might be very relevant in your scenario.
you could also use a Saga that keeps track of the process and than create a command like "recallneeded" when the time is up. it also keeps track of events that tells the Saga to complete if there was a call within the 50 days. (Keep in mind that a Saga is part of your Domain logic and acts as an AR if doing DDD)

Rest API needs additional operations - how to structure?

My application deals requires users to sign up before they can use the service and to do that they create an Application. The initial plan of the interface is as follows...
POST /Users/Applications - Creates an application and returns a unique identifier.
GET /Users/Applications/{id} - Retrieves an existing application.
PUT /Users/Applications/{id} - Updates an existing application.
DELETE /Users/Applications/{id} - Deletes an existing application.
This seems very clean and logical and makes best use of the HTTP verbs. However what if I now need to do other operations on an application e.g.
ActivateApplication - once all of the data is in the system by using PUT I now want the users to activate their application. This isn't just a matter of updating a status on the application using PUT, there are several additional jobs that should be done to activate an application such as emailing the HR dept. to inform them a new application has arrived.
PrintApplication - when called from the client prints the application to the office printer. (Not an ideal example but you get the idea I'm sure!)
How would I structure my REST interface to handle this type of request? Maybe something like this...
POST /Users/Applications/{id}/print
POST /Users/Applications/{id}/activate
...for activate I'm changing state so I believe I need to use POST. I understand REST is about documents but how do I structure my API when I need to perform operations on documents, not just get and update the document itself?
This Martin Fowler's article states that:
Some people incorrectly make a correspondence between POST/PUT and create/update. The choice between them is rather different to that.
When I try to decide between PUT and POST I follow the next rule:
PUT -> Idempotent
POST -> Not Idempotent
Idempotent means that there's no difference between performing one and multiple operations. The DB data will be the same after the first operation and after each of the other operations.
In case of not-idempotent operations, every performed operation changes the data in the DB.
That's why PUT is usually used for UPDATE operations and POST for CREATE. But this is not the correct rule.
Comming back to your question, in my opinion you are using POSTs correctly as a not idempotent action, because multiple calls to ActivateApplication will send multiple emails.
Edited
As #elolos has commented, following the Single Responsability Principle, sending an e-mail should be another responsability not directly linked to Update the State. Handle an event when the property changed in order to trigger processes like sending emails would be a better approach. This way ActivateApplication operation may be idempotent and be called using PUT Http method.

RESTful Soft Delete

I'm trying to build a RESTful webapp wherein I utilize GET, POST, PUT, and DELETE. But I had a question about the use of DELETE in this particular app.
A bit of background first:
My webapp manages generic entities that are also managed (and, it happens, always created) in another system. So within my webapp, each entity will be stored in the database with a unique key. But the way we will be accessing them through URLs is with the unique key of the other system.
A simple example will make this clear, I think. Take the URL /entity/1. This will display information for the entity with ID 1 in the other system, and not my own system. In fact, IDs in my system will be completely hidden. There will be no URL scheme for accessing the entity with ID of 1 in my own system.
Alright, so now that we know how my webapp is structured, let's return to deleting those entities.
There will be a way to 'delete' entities in my system, but I put quotes around it because it won't actually be deleting them from the database. Rather, it will flag them with a property that prevents it from appearing when you go to /entity/1.
Because of this, I feel like I should be using PUT ('deleting' in this way will be idempotent), since I am, from the perspective of the data, simply setting a property.
So, the question: does the RESTful approach have fidelity to the data (in which case it is clear that I am PUTing), or the representation of the data in the app (in which case it seems that I am DELETEing)?
You should use DELETE.
What you intend to do with your data is called "soft deleting": you set a flag and avoid flagged items from appearing. This is internal to your webapp and the user doesn't have to know that you're soft deleting instead of deleting or whatever you want to do. This is why you should use the DELETE verb.
I think there is no definitive answer. I'd rely on whether 1. the soft-delete, recover and destroy actions are an actual feature of your api OR 2. soft-delete is merely a "paranoid" database engineering pattern.
The "soft" deletion is transparent for the api client, in which case using the DELETE verb seems like the way to go
Everything is as if the item was to be removed once and for all, but engineers want to keep it somewhere in the database
Api clients have the ability to recover or destroy the soft deleted resource, in which case soft deletion and recovery can use POST on a different action url like /resource/:id/softdelete and the destroy action would be the one using DELETE.
Another way to go may be to use DELETE with no query parameter to soft delete, and add ?destroy=true to actually destroy. But this approach seems less explicit and more prone to errors.
The DELETE method has very specific semantics in HTTP, which must not be overloaded
or stretched by a REST API’s design. Specifically, an API should not distort the intended
meaning of DELETE by mapping it to a lesser action that leaves the resource, and its URI,
available to clients. For example, if an API wishes to provide a “soft” delete or some
other state-changing interaction, it should employ a special controller resource and
direct its clients to use POST instead of DELETE to interact.
Source: Rest-API Desgin Rule book by Mark Massé
Suggestion:
POST: /entity/1/your-soft-delete-controller-name

CQRS: how do you retrieve information about an executed command?

In most command interfaces I've seen, there is typically an "Execute" method which takes takes a command input and either returns void or some generic structure indicating if the command executed successfully or not (we are using the latter). Now, I've never thought of this before, but we suddenly got the need to know some more details about the result of the command than what you can expose generically.
Consider the following example:
you have a team and you are creating a screen where you can add members to your team. The members of the team are shown in a grid below the "add new member"-stuff. Now, when you press "add new member" you want to run some jquery/roundohuse/whatever and add the new member to the list of team members. No problems so far, but: you also want to include some identification data in a hidden field for each member and this id-data comes from the server.
So the problem is: how can I get that id-data from the server? The "AddNewTeamMember" command which I am pushing through the "ExecuteCommand"-method does not give me anything useful back, and if I add a new query method to the service saying something like: "GetLastAddedTeamMember" then I might just get the last entry added by someone else (at least if this is data which is very aggressively added by different users). In some situations you have a natural unique identifier generated on the client side which we can use, but for team members we did not.
Given that you have no choice but to update an on-page widget when another command completes, I see two choices for you:
Shoot off the command, display something locally that indicates it is submitted, and then wait until you get a notification from the server that the team member list has changed. Update the widget to reflect that.
Add a correlation ID to your command when you submit it, and add the team member provisionally locally to the list. When you get a confirmation from the server that a team member update happened because of your correlation ID, update your local data.
I would suggest the first approach, where the "provisional indicator" could be throwing a marked version of the normal indication into place; then, when you finally get an update you should have the data you need.
Given you went with CQRS to solve this problem I assume you have frequent updates to the content of those widgets happening in the background already, so have presumably solved the "background update" problem.
If not, I suggest you either ditch CQRS as a bad - over-complicated - solution in your problem space, or solve the background update problem first.
If you want to add an existing team member, you should query the read side of your application for this data. If you need to add a new team member, you have to consider if it's necessary to show the user in the grid below at once. Can you wait until the team member is in place on the read side? You can also query a service on the server side to get an unique ID (it can return a GUID). Then you add the team member to the grid, and of course, send the command to the server. But, if it's possible, try to design the application in a way that you don't have to show the team member at once. It's also possible to give the user a message saying something like this: "Team member added, waiting for response from server.". Then use AJAX to query the read side for new team members. When it appears on the read side, show it in the grid. You might have to deal with team members added by other users, but does it matter? CQRS gives you a great way to collaborate with other users, so maybe you should take advantage of that. As I see it; CQRS forces you to think different, and that may not be a bad thing.