Workflows - a generic approach

Jan 12, 2011 at 10:30 PM

I am curious where you guys are at with the workflow implementation - in the docs I see the intended state transition diagram, but I'm not seeing it in code.  If someone can point me to where it is or intended to go, that would be great.

The reason I ask is a few months back I raised the question around workflows in Orchard - we have a generic approach using Autofac, a capability exposed in net4's System.ComponentModel.Composition, and the Stateless state machine implementation. The registration dance was a bit involved and it became apparent that a DSL is required to make it consumable by a larger audience.

Fast forward to now and the result is FluentWorkflow which is now available on codeplex.  As a contributor to Autofac, I created the AutofacContrib.Attributed project that supports the mechanism.  AutofacContrib.Attributed 2.4 supports the FluentWorkflow registration model as well.

I would like to implement workflows in orchard on my own branch - it would help with my documentation/samples for the fluentworkflow site. 

If you are interested in reading up on FluentWorkflow, I recommend the intro which describes the problem it solves and the configuration DSL it provides.  That's a two minute read that nails it down pretty succinctly.

To see it in action, grab the source and check out the sample.workflow.process project which shows a running console-based application using it.   You'll grasp that app quicker than that intro document.

This is pre-beta from a project standpoint due to documentation and supporting samples (I am working on a sample MVC app alongside it).  The code itself is being used in production in my company and one other.  

Thank you,

-Steve

twitter: stevehebert

 

Coordinator
Jan 12, 2011 at 10:33 PM

Sounds like a great module opportunity. Not sure what you mean by it's not implemented. As a workflow it's not dynamic or anything but transitions from published, draft, etc. are fully implemented. There may be some differences with the very old initial spec that you are referring to but I think the current implementation is by design.

Jan 12, 2011 at 10:40 PM

Sorry - my searching was off the mark (badly).   Now I'm seeing it in BlogPostAdminController.  I think that's a root that I can start working from!

From here, it looks like I should be able to make the functionality into a module (my next thing to look at).  

Thank you,

-Steve

 

 

 

Apr 19, 2011 at 9:15 PM

Any news on this?

Apr 20, 2011 at 1:27 AM

I started work on this, but I'm lacking a good definition of what people are looking for in a workflow in orchard.  If I had more definition of what people are looking for, it would be a fun project to fill this out.  I've been working on the fluentworkflow documentation and have it to a good spot.  I am using fluentworkflow on a couple of projects and it works extremely well.  Let me know if you have any ideas on you'd like to have it applied to orchard.

 

-Steve

Apr 20, 2011 at 8:23 PM

I think that the most common use of workflows within a portal or CMS is to give users a way to customize the approval workflow and then in general a way to move content items between various lists and set its attributes according rules and conditions specified in the workflow.

Any such workflow system should support:

  • starting the workflow on events such as a new content item created, modified, deleted, attribute changed... - these workflows are associated with a specified list of content items or even with a content type alone (then it would start on a content item in any list),
  • starting the workflow on global events of the portal, such as a user logs on, a new list is created, ... - there could be an extensibility point for modules,
  • starting the workflow manually by user or through the portal workflow API,
  • activity types that operate on content items, mainly CRUD,
  • some versioning support,
  • way to visualize state of the workflow,
  • writing to workflow log, i.e. workflow history, probably through a special activity (WriteToHistory),
  • ability to author workflows visually (drag and drop activities, connecting shapes, ...),
  • creating custom activities usable in the workflow,
  • ability to collect data in custom forms.

I thought that a simple yet powerful way would be to base Orchard workflows on Windows Workflow Foundation. You took a different path, Steve - your workflows are using stateless - what are advantages over WF and cons, if any?

This is just to start discussion on the workflow topic in the Orchard.

Orchard Team - any work is being done on the workflow feature?

Coordinator
Apr 20, 2011 at 8:52 PM

I have been working on this topic for a few weeks now, puting the plumbing in place, by defining Events, Conditions and Actions. Like in Drupal Rules module. Other modules can provide Events and Actions. It's not public code yet though, but should be soon.

Apr 20, 2011 at 9:12 PM

Great to hear that, Sébastien. Is it based on the WF?

Coordinator
Apr 20, 2011 at 9:20 PM

Not at all. And it's completely stateless, so it might not do everything listed here, it's an infrastructure to define Events (Comment was created, User logged, ...) which are filtered by Conditions (evaluating expressions using the event's published properties, and Orchard public ones) then executing an Action (Publish Content Item, Send an email, ...).

It's just orchestrating events and actions, and any module can declare them. It also porvides admin screen to manage those "Rules" or "Workflow", as you want to call them. There are still a few things I don't want to announce here until it really works, but it's definitely the tool I would like to use personally, based on my own experiences. When it's done you might still want to develop a more complex one, or more user friendly. I am targeting Web Devs, not end users, so no fancy drag and drop or connectors here ;) Forms, and .... secret.

Coordinator
Apr 20, 2011 at 9:22 PM

Oh,, and though I am part of the Orchard Team, it not an offically developed one, like many we do on our spare time.

Apr 20, 2011 at 10:26 PM

At least the parts for defining events could be used on the heavyweight WF solution. I know it depends on your spare time but when do you estimate you could release the code you're working on? Is it days, week or months from releasable?

Also, are there any official information from you guys on the Orchard Team if any workflow support is being considered for implementation?

Taken from http://www.orchardproject.net/docs/feature-roadmap.ashx, "Publishing – Workflow/permissions, draft approval, history (restore from)" means WF-like solution?

Developer
May 25, 2011 at 10:14 PM

Sebastien, have you managed to move your project forward? I recently thought about writing a Workflow module and suddenly found this post (which was a pleasant surprise btw;). 

It would be a very helpful stuff to use with payment transaction processing I'm currently dealing with.

Coordinator
May 25, 2011 at 10:48 PM

Was too busy with TechEd ... but I can see I will have more free time now. Finishing some stuff on the taxonomy, then going back to this one.

May 25, 2011 at 10:53 PM

I was also wondering how that was going. Some of the work I'm doing with relationships and shapes could get really interesting on top of this :)

Jun 9, 2011 at 7:31 AM

hi Sebastien, 

I am looking into doing this as well, just wondering how the project is going, I would be happy to contribute something towards this project.

Thanks

Jul 29, 2011 at 7:45 AM

I would like to revive this discussion.

Tuan Truong said:
I'm looking into building the workflow in Orchard like how it works in Drupal:
You defines groups that have accesses to the workflow.
You define workflow states for each content type.
You created rules for each transition ( a content-type state is moved from one to another), the rules include which groups of people allowed to change the transition (back and forth), and then what actions will happened when this happened (like sending emails and stuff).
I don't know if anyone have started something similar yet, but if you guys could please help me on which approach would be the best for this, it would be very helpful.
I have saw a discussion on codeplex (http://orchard.codeplex.com/discussions/241520) but there seems to be no further info yet.

It would certainly be interesting to provide a generic way to define states, events and actions. I would be happy with it being implemented internally so that we can write modules on top of it. Having a nice UI on top sounds too complex to do in a generic yet easy-to-use way.

By the way, I think that your "groups" have more to do with access control (which is already provided through Role and Permission).

@Sebastien: Would you be interested in sharing what you have so far even if it isn't 100% working?

Coordinator
Jul 29, 2011 at 10:20 PM

I can share what I have done, and would be happy if you could continue the work, but it would need two things. First for me to explain what is the idea behind this module, and maybe you would not agree and decide to do something else. Also, I'd like to discuss with the Core team so that we agree with how it should be done, and thus you would be sure we wouldn't reimplement it in parallel ;)

The basic principle is that it's not a Workflow engine, but a Rule engine:
A Rule is made of an Event, a Condition and an Action. Events and Actions are provided by IEventProvider and IActionProvider, defined in any module. They have a Name and a localized description, like "A comment has been created"; "Some content has been published". Actions are "Send an email", "Publish a Content Item", "Redirect a user to xxx" ...

A condition is an evaluable expression returning trur or false. The evaluation engine should be pluggable, usign the current IRuleEngine for the default implementation. We could imagine using Javascript or C# as an alternate condition engine. We could also let each Rule decide what engine it wants to use. This engine would come with a Drvier, to define the Editor UI. The simplest one is a textarea to enter the condition.

Modules have a dependency on the Rules engine, and actions are executed using the Event Bus in Orchard, which is able to execute anything by its name.

Event will provide named parameters, like the Tokens module (be we don't have it yet) and can be used in the Condition and in the Action.

You can see a Workflow as a set of Rules, and it might also be an interesting concept to implement at a later time.

Jul 29, 2011 at 10:30 PM

I am happy with this design; so far it fits my needs.

Let me know when you can upload it somewhere (maybe as a codeplex project so that we can all work on it).

Aug 25, 2011 at 3:22 AM

Hi Sebastien and phkuate,

Is there any news on this yet, would be great if you guys could share some of the stuff that could guide us in the right direction to work on this.,

Thanks very much

Coordinator
Aug 25, 2011 at 4:33 AM

Yes there are some news. This module is now our current priority, and should be available by the end of next week as a preview. It's compatible with Orchard 1.2. In parallel we think it would be pretty easy to create a Workflow module which would do what it states: workflows. Look at this video about the Workflow module in Drupal. We already know how to implement it in Orchard, super easy.

http://www.drupalove.com/drupal-video/workflow

Could be done by someone in the community.

Aug 28, 2011 at 11:42 AM

I have been thinking some more about this and I would like to make the following observations:

(Note that, this part focuses on the core implementation, not the end-user experience)

- A Condition is really just an Action that triggers another Action. This is important to realize because all the properties of a Condition should be applicable to an Action and vice-versa. For example, any Action should have the ability to surface an Editor UI (to take in parameters). From a programming point of view, this ability is the same as being able to send an email or change a content's field or trigger another Action or execute any arbitrary piece of code...

- I would like to rename IRuleEngine to IRuntimeEngine or something like that. It seems to make more sense.

- Regarding using the Event Bus to execute the Actions, I think that's fine, especially since the Event Bus can be replaced. I can see myself writing another implementation using something like Quartz.NET :) (In practice, it might be a hybrid approach using the default Event Bus for "normal" events and Quartz.NET for Actions...)

 

From a end-user point of view, we can have a module providing a set of common Events and Actions with their Editor UI, etc.
A IfAction would be an implementation that shows two input areas, one to enter the condition, and the other to enter the (sub-)action. A SendEmailAction would be an action that asks for the email details to send.

So, to enable notifications to moderate anonymous comments, the user would have the ability to create:
Event: When "Comment is created"
IfAction_NeedModeration: if Author is Anonymous then Run SendEmailAction_CommentToModerate
SendEmailAction_CommentToModerate: SendEmail(To = AllUsers where Role==Moderator, Subject = "TODO", Body = "Comment in need of moderation...")

Of course, the IfAction_NeedModeration and SendEmailAction_CommentToModerate can be the same, but I split them to show that it was possible. 

This module would be quite equivalent to the one presented by Sebastien.

However, we would still have the ability to write complex events/actions and present easy-to-use UI to the end-user. So, for this example, we could have a specialized Moderation module which surfaces a checkbox "Require moderation for anonymous comments" in a blog's settings. And behind the scene, that checkbox would enable the same functionality as described above.

It would be possible for this specialized Moderation module to bypass all this event/action interface and use handlers, etc. But I think that the event/action is a nice API for certain tasks. For example, it could provide a binding to run Orchard Commands (as sub-actions) out of the box.

Now that I think about it, Commands and Actions are quite alike. Maybe there is an opportunity for sharing things, making any action command-able and any command action-able :)
Yes... Maybe we should remove the notion of "Action" and just re-use Command, while extending it where needed.

What do you think?

Pierre Henri.

Coordinator
Aug 28, 2011 at 5:06 PM

A condition is almost like an action, but in terms of UI they are different, because as you explain it a condition could take another 'existing' action as a parameter, unless each actions can decide to shut off the action execution cycle. It makes things harder to implement. Though we had already thought about being able to select the type of condition. The current implementation uses the Layer's module, which is really sufficient for a v1. As it would be extensible, anyone could add new types of editors. To be discussed, but I don't disagree a condition could be another category of actions. Note that we can currently have several actions in sequential order per rule.

We don't use the Even bus anymore, and I also thought about having scheduled actions, which would be easy to do with the current architecture. There would be a "Scheduled Event" which would create tasks from the Scheduled tasks module (existing one), and each time the task is ran, then would create the next scheduled task at the customized time. So it's already doable, it will have to be done for v1 of the module I think.

Ys a moderation system could be done with rules, but I think users might be better served with a dedicated module and a dedicated UI, which would let them use the Rules module to define what actions to take. I really liked the way it's done in drupal. It doesn't handle what to do, just permissions and comments. It would trigger actions that the Rules module can depend on.

The commands story was already in mind. There are two solutions: an Action which would expose a textbox where the user defines the command text, using tokens given by the event; or an Action provider which would expose all the available actions by name, and generate the form dynamically. The two options are even possible side by side.

NB: Just a quick note about the status. I found some time to work on this module this week, and made very nice progress, to the point that's it currently usable. And it went further than what was expected. In fact we are actually currently shipping three different module to have this one working. It consists of Tokens, Forms and Rules. Token was explained by Bertrand in his blog, and is necessary so that Events can provide contextual and global data to the Condition and the Actions. Forms is necessary to let external module define Actions, Events, and there corresponding forms. This is an API, where you define forms programmatically. For more insight you can look at what Drupal is doing with their Forms API module. This module should have more responsibilities in the future. It allows any module to customize forms, like adding Ajax, validation, altering existing forms by adding new field (captcha) and could drive dynamic form creation modules, or polling. Just take a look at all the module using the Froms API in Drupal for a broader vision.

All these modules required little changes in Orchard core, which means they will be compatible with 1.3, and that 1.3 won't create breaking changes from 1.2 because of them, which is always good news.

Aug 28, 2011 at 6:31 PM
Edited Aug 28, 2011 at 6:34 PM

OK. I was really looking at it from a low-level perspective (ie: what goes in the "core"). How it gets implemented in each module should be up to the module developer.

From what you are saying everything will actually be in modules (Rules, etc.) so, that's fine; we can always rewrite them in different ways if need be.

 

About the Command story, I am not sure that we are talking about the same thing. I am saying that the concept of "Action" is the same as the concept of "Command". They are both discrete sets of instructions that can receive inputs and be executed to do "stuff" (one difference, that I consider small, is the way they receive inputs, and that can be abstracted to work in command line as well as GUI).

Command already exists in Orchard and there are already a bunch to do various stuff, so why create "Action"? It feels like you would have to re-implement all this commands as actions. And developers would always wonder if they should write a Command or an Action or both. When I look at all the commands that already exist, I feel like I would want them available as actions as well. And when I start writing actions, I will want them as commands as well (so, I can use them in recipes, for example).

I know it is a bit late to make such a big change... I wish I had this "revelation" earlier :) The annoying thing is that once we start using actions, it will be harder to switch to commands.

 

Looking forward to this upcoming release.

Coordinator
Aug 28, 2011 at 8:54 PM

I follow you from the beginning about commands, and as I said this can be done by default. To declare an action to the module, you create an IActionProvider, which looks like INavigationProvider. You can describe a set of actions from one class, which means for instance we will have a CommandActionProvider class, which will go through all available Command in the system, and declare them to the rule system. When requested for execution, it will forward to the concrete command. I will commit the code soon and you will be able to play with it for early review.

Aug 28, 2011 at 10:22 PM

Great. Thanks.

Sep 6, 2011 at 1:10 AM

Hi Sebastien,

Any ETA on the release of the rules/action/workflow module? to the public.

Thanks,

-venkat.

Coordinator
Sep 6, 2011 at 8:08 PM

I have pushed the references to those new modules on the 1.x branch. You can try to play, and I might write something on how to use it, because it won't be obvious for everything.

Sep 6, 2011 at 8:12 PM

Thanks Sebastien, nice work. Will you be also posting a module in the Gallery with the dependent modules Forms and Tokens?

 

-venkat.

Coordinator
Sep 6, 2011 at 8:34 PM

Right now Comments has a dependency on them, and Comment being in the main distribution, they might also end up in the main distrib too.

Sep 6, 2011 at 10:03 PM

I downloaded the source. See the comments rules code but not the Rules/Forms modules. 

Sep 6, 2011 at 10:03 PM

I downloaded the source. See the comments rules code but not the Rules/Forms modules. 

Coordinator
Sep 6, 2011 at 11:21 PM

They are in sub repositories. They should be downloaded automatically by TortoiseHg, if you have the latest version.

Sep 7, 2011 at 1:10 AM

Thanks Sebastien, appreciate the help

Sep 10, 2011 at 3:35 AM

Thanks for releasing Rules module. To begin with, I've downloaded Rules module, created new rule to create Info message whenever some one publishes content. I made sure rule is active and there is a action associated to it. After adding rule, I published few pages but not seeing any messages generated as per rule. Where are this messages logged? Also, does anyone have example for rule Boolean expression?

Pardon me if I'm not understanding module correctly...

Thanks!

Coordinator
Sep 10, 2011 at 4:21 AM

Have you enabled the rule ?

It's a pretty new one, and we are still doing some changes on it. And no doc right now ...

Sep 10, 2011 at 1:14 PM

Yes, rule is enabled. Any ETA on when latest changes and doc will be available?

Nov 14, 2012 at 8:36 AM

sebastienros, why I can't find your source code and the project you refference "sample.workflow.process", currently our team will use the WF, but can find a product to suit it, could tell me where I can find you demo project or send the "sample.workflow.process" to me? Thanks so much