This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 225892 - Example EMF workflow model
Summary: Example EMF workflow model
Status: CLOSED FIXED
Alias: None
Product: EMFT
Classification: Modeling
Component: MWE (show other bugs)
Version: 0.7   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Bryan Hunt CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-04-06 01:11 EDT by Bryan Hunt CLA
Modified: 2010-05-27 07:53 EDT (History)
11 users (show)

See Also:


Attachments
EMF workflow model (170.72 KB, application/zip)
2008-04-06 01:13 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (987 bytes, application/zip)
2008-04-06 01:13 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (212.28 KB, application/zip)
2008-04-18 11:24 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.03 KB, application/zip)
2008-04-18 11:25 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (252.52 KB, application/zip)
2008-04-23 00:18 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.03 KB, application/zip)
2008-04-23 00:19 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (275.92 KB, application/zip)
2008-04-26 00:01 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.08 KB, application/zip)
2008-04-26 00:02 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (309.80 KB, application/zip)
2008-05-13 22:55 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.65 KB, application/zip)
2008-05-13 22:55 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (331.46 KB, application/zip)
2008-05-16 22:48 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.30 KB, application/zip)
2008-05-16 22:48 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (395.20 KB, application/zip)
2008-05-21 00:19 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.31 KB, application/zip)
2008-05-21 00:20 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (760.33 KB, application/zip)
2008-05-25 14:10 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.35 KB, application/zip)
2008-05-25 14:11 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (776.59 KB, application/zip)
2008-05-26 10:16 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (840.00 KB, application/zip)
2008-06-01 10:51 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.39 KB, application/zip)
2008-06-01 10:52 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (922.27 KB, application/zip)
2008-06-03 23:19 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (948.26 KB, application/zip)
2008-06-12 00:47 EDT, Bryan Hunt CLA
no flags Details
Sample declarative workflow (290 bytes, application/xml)
2008-06-12 00:48 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (1014.47 KB, application/zip)
2008-06-29 11:05 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (1019.05 KB, application/zip)
2008-07-12 23:07 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (1023.56 KB, application/zip)
2008-08-03 08:59 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.42 KB, application/zip)
2008-08-15 22:23 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (968.39 KB, application/zip)
2008-08-15 22:26 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (990.54 KB, application/zip)
2008-09-01 13:56 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.47 KB, application/zip)
2008-09-01 13:57 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (999.68 KB, application/zip)
2008-09-28 10:39 EDT, Bryan Hunt CLA
no flags Details
Sample workflows (1.47 KB, application/zip)
2008-09-28 10:40 EDT, Bryan Hunt CLA
no flags Details
EMF workflow model (1.01 MB, application/zip)
2008-11-30 21:13 EST, Bryan Hunt CLA
no flags Details
EMF workflow model (1.01 MB, application/zip)
2008-12-03 20:38 EST, Bryan Hunt CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bryan Hunt CLA 2008-04-06 01:11:56 EDT
Here is an example EMF workflow model.  The model allows you to create a pure EMF workflow, or to mix in POJOS.  Both types of models will run standalone.  Only the pure EMF workflow will run in an OSGi runtime.  I didn't want to deal with "classloader hell" in the simple example.

The code was generated with EMF 2.4.0M6.

The attached workflow.zip contains the workflow model, the EMF generated editor, an action to run the workflow from a runtime workbench, an example of a user supplied EMF workflow component (LogMessage), and an example of a user supplied POJO workflow component (Hello).

The attached test.zip contains some example workflow models.  Import the project into your runtime workbench.  You may right-click on the emf.workflow and select "Run Workflow" to execute the workflow.  The pojo.workflow can only be executed successfully from the command line.

To run the sample workflows from the command line, create a Java launch configuration.  On the Main tab, the Project should be set to org.eclipse.emf.wf.core, and the Main class is org.eclipse.emf.workflow.main.Workflow.  On the Arguments tab, the first program argument should be the path to the workflow to execute, for example, ${workspace_log}/../test/workflow/test/pojo.workflow.  The Classpath tab should include the following projects / plugins: org.eclipse.emf.wf.core, org.eclipse.emf.wf.examples, org.eclipse.emf.common_2.4.0.v200804012208.jar, org.eclipse.emf.ecore.xmi_2.4.0.v200804012208.jar, and org.eclipse.emf.ecore_2.4.0.v200804012208.jar.

To create a new workflow, you may create the XMI with your favorite editor using the samples as a template, or you may use the generated editor in the runtime workbench.  Launch the runtime workbench, create a new generic project, create a new Example EMF Model Creation Wizards -> Workflow Model.  Click Next and give the a model a name with a .workflow extension.  Click Next and choose Composite Workflow Component as the Model Object.  Click Finish.  When the editor appears, add a new child to the Composite Workflow Component of either Message or Pojo Workflow Component.  Use the properties view to configure the children.
Comment 1 Bryan Hunt CLA 2008-04-06 01:13:06 EDT
Created attachment 94986 [details]
EMF workflow model
Comment 2 Bryan Hunt CLA 2008-04-06 01:13:54 EDT
Created attachment 94987 [details]
Sample workflows
Comment 3 Marc Dutoo CLA 2008-04-18 11:00:21 EDT
Eclipse JWT newsgroup discussion :

Hi Bryan

I second everything Michael has said.


Implementing a transformation for your model would allow you to use the full JWT editor feature set (including export to other BPM formats).

We'd be willing to help you do this. There are already good samples : look in the eclipse technology.jwt CVS, the "transformations" subtree contains a sample stub transformation you may start with, as well as several working transformations that will show you how to use ATL or XSL as transformation technologies (if you'd rather use JET or Acceleo, we got tutorials - well, any technology is ok !).


In addition, I note an interesting point about your sample : it showcases how your model may be extended concretized, meaning that in addition to the core workflow model, domain specific workflow model (especially domain specific actions and task implementations) inheriting from it can be defined.

This can be done in JWT, but for now such extended actions would not show differently in the UI, so their specific properties could not be set and therefore they would not be any more useful than normal actions.

However, we're currently working on how to allow to extend the JWT metamodel, which will imply being able to display such extended properties in the UI, which would fill you needs. So we're both rather in the same mindset ;)

Your sample / idea about this advocates a typed action extension mechanism. Another one would be mere key-value pairs on actions, which is simpler. I rather like the idea of typing actions since the PVM runtime (common future Bonita and jBPM BPM engine) does the same, and it would allow to control consistency of action types within a business process, as well as which ones are for example BPEL-compatible versus XPDL-compatible.

However if typing is too harsh it might be cumbersome to do extensions. Typically, having to write another EMF model whenever a custom property needs to be added and generate its companion Java code is a development task but (I think) should not be one, since mere users might want such custom properties.

I'm putting the dev mailing list (jwt-dev@eclipse.org , you're welcome to subscribe) on cc so we can go further on this :)


Regards
Marc Dutoo
JWT Team co-lead
Open Wide

Mickael Istria wrote:

> Bryan Hunt a écrit :
>
>> I just ran across the Eclipse JWT project and it seems that it either overlaps or compliments MWE - I'm not quite sure which.  Have the two groups had any discussions on collaboration?
>>
>> I am, hopefully, cross-posting to both groups and including a link to my starter EMF based workflow engine for discussion.
>>
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=225892
>>
>> Bryan 
Comment 4 Marc Dutoo CLA 2008-04-18 11:01:45 EDT
Eclipse JWT technology discussion - initial Michael post (forgotten, sorry)


Hello,

I took a look at MWE, and here are a few thought that could maybe show you some differences between MWE and JWT. (However, I am not a wise old man in JWT -and Eclipse more generally-, so that I apologize in advance if I make mistakes).


MWE is a modeler for workflow based on EMF. According to what I quickly saw when I tried it, it defines a metamodel for workflows, and allows users to write and run a workflow defined in this metamodel.

JWT is aimed to be a complete and generic tool for workflow designers. It includes a graphical editor that allows to "draw" a workflow. It uses an internal metamodel for workflows which is compatible with AgilPro Workflow Engine.
In the future, JWT should include some runtime tools that would allow user to monitor his workflow from JWT with a large and open set of workflow engines (we are currently focusing on Bonita).

We recently integrated into JWT a transformation framework to give it more compatibility with other standards such as XPDL, BPMN... (the list is short for the time, but it may be extended). XPDL will give to JWT the ability to design workflows that will be compatible with Bonita, and BPMN will make JWT compatible with other graphical workflow editors.

As you can see, we are trying to make JWT as complete and general as possible.


The thought that came to my mind when I discovered MWE workflow engine was: "JWT could handle it".
Including a new workflow engine into JWT can be done in a few steps (that may not be so easy to implement than to desctibe them):
- Extend editor and JWT metamodel to make them support additional informations necessary to your metamodel (that is the most difficult point since changing metamodel must be done cleverly)
- Add a transformation from JWT internal metamodel to your workflow engine metamodel, so that JWT can produce MWE files
- and, if you want a full integration, add a launcher for your workflow engine, and everything to call it from the UI.



I hope that all this monologue answered your questions, and that it gave you some ideas for a possible future compatibility between JWT and MWE.

Mickael 
Comment 5 Bryan Hunt CLA 2008-04-18 11:24:27 EDT
Created attachment 96611 [details]
EMF workflow model

Here is an updated model.  I've added the ability to model inputs, outputs, and connect them together.  The next thing I want to model is forwarding an output from a UnitOfWork to it's parent composite.  I'm not completely satisfied with the way inputs and outputs are modeled, so if there are any better suggestions, I'm happy to hear them.  One thing that would be interesting is to validate a constraint that a component with an output must be executed before a component with an input connected to that output.  Anybody have any good pointers on how to get started with the EMF validation framework?  I think the next big piece is parameterization of a component.
Comment 6 Bryan Hunt CLA 2008-04-18 11:25:46 EDT
Created attachment 96612 [details]
Sample workflows

I've updated the sample emf workflow to include a message producer that outputs a string.  That output is connected to the input of the message logger.
Comment 7 Bryan Hunt CLA 2008-04-18 11:30:53 EDT
(In reply to comment #3)
> Your sample / idea about this advocates a typed action extension mechanism.
> Another one would be mere key-value pairs on actions, which is simpler. I
> rather like the idea of typing actions since the PVM runtime (common future
> Bonita and jBPM BPM engine) does the same, and it would allow to control
> consistency of action types within a business process, as well as which ones
> are for example BPEL-compatible versus XPDL-compatible.
> 
> However if typing is too harsh it might be cumbersome to do extensions.
> Typically, having to write another EMF model whenever a custom property needs
> to be added and generate its companion Java code is a development task but (I
> think) should not be one, since mere users might want such custom properties.
> 

Could you elaborate on this a bit more.  I'm not quite following your comments.  When you talk about key value pairs, I'm wondering if you are talking about what I might consider parameterization of the workflow component where the component might have a set of keys is uses to look up parameter values supplied by the user at runtime in a map.
Comment 8 Bryan Hunt CLA 2008-04-18 11:33:18 EDT
(In reply to comment #4)
> MWE is a modeler for workflow based on EMF. According to what I quickly saw
> when I tried it, it defines a metamodel for workflows, and allows users to
> write and run a workflow defined in this metamodel.

One thing to note for others that might be interested in this work:  MWE is currently not based on EMF, and thus the intent of this bugzilla is to propose such an EMF model.
Comment 9 Marc Dutoo CLA 2008-04-18 14:08:53 EDT
Yep, exactly.

Basically, free form (property map-like) data on Actions (executable tasks) is useful for the end user to use like annotations without requiring heavy development. Typing or subtyping actions is interesting for workflow validation and consistency check and developing domain specific sub Actions.

Note that there is an interesting discussion ongoing in the JWT developer mailing list with someone else that is in the same position as your are, you're welcome. I'll try to feed information.
Comment 10 Bryan Hunt CLA 2008-04-23 00:18:27 EDT
Created attachment 97126 [details]
EMF workflow model

I've modeled the inputs and outputs as parameters now.  Inputs and outputs may be specified on a composite as references to inputs and outputs of children of the composite.  The idea is that a editor could treat the composite as a black box and show only the inputs and outputs of the composite.

 I've also modeled the WorkflowContext and WorflowEngine in EMF allowing them to be serialized, but this has not been tested.
Comment 11 Bryan Hunt CLA 2008-04-23 00:19:36 EDT
Created attachment 97127 [details]
Sample workflows

Updated sample workflows
Comment 12 Bryan Hunt CLA 2008-04-26 00:01:25 EDT
Created attachment 97709 [details]
EMF workflow model

Execution of the elements in a composite is now done using a strategy pattern.  I've modeled a serial and parallel execution strategy.  The parallel execution strategy needs to use thread pooling in the future.
Comment 13 Bryan Hunt CLA 2008-04-26 00:02:14 EDT
Created attachment 97710 [details]
Sample workflows

Updated the composite workflows to use the serial execution strategy.
Comment 14 Bryan Hunt CLA 2008-05-13 22:55:07 EDT
Created attachment 100105 [details]
EMF workflow model

Added a simple launcher for a workflow.  Added basic state information to the workflow component.  More work needs to be done in these areas.
Comment 15 Bryan Hunt CLA 2008-05-13 22:55:56 EDT
Created attachment 100106 [details]
Sample workflows

Added a sample launch configuration.
Comment 16 Bryan Hunt CLA 2008-05-13 22:57:44 EDT
This latest update also includes thread pooling for parallel component execution.
Comment 17 Bryan Hunt CLA 2008-05-16 22:48:03 EDT
Created attachment 100754 [details]
EMF workflow model

I wasn't happy with the design of the parameters, so I eliminated InputParameter and OutputParameter.  This makes Parameter much more extensible.  I added a ParameterConnection to facilitate the connection of an output to one or more inputs.

I've been thinking about also changing the WorkflowState enum to use the state pattern which would make it extensible, but I haven't found a good way to combine the results of executing the components of a composite into a single state.  Ideas are welcome.

I also moved PojoWorkflowComponent into it's own model making it a proper extension of the workflow model.
Comment 18 Bryan Hunt CLA 2008-05-16 22:48:43 EDT
Created attachment 100755 [details]
Sample workflows

Updated the sample workflow for the new model.
Comment 19 Marc Dutoo CLA 2008-05-19 09:31:16 EDT
Hi Bryan

I've taken a look at your updates, here is my feedback.

"The idea is that a editor could treat the composite as a black
box and show only the inputs and outputs of the composite." -> I like the "black box" point of view, it is very much in sync with allowing any kind of JWT Action / WorkflowComponent extensions, and with my latest tries in enabling extensibility of the JWT model (more soon on mailing list).

From what I've understood (please correct me if I'm wrong), you want to make primarily a runtime workflow model, i.e. a workflow model that not only can be executed but has even runtime state information in it.

So it is not surprising that your model has quite a few things in it that are only runtime (and not devtime) : WorkflowState, WorkflowEngine... This "runtime" flavour has the advantage of making it a model that can directly be run (if only at development time by the developer). However I'd still advise to carefully make the separation between devtime information and runtime information.

For example, maybe XxxWorkflowOrchestrator should be renamed to something like XxxWorkflowOrchestrationStrategy, therefore making it more like information and less like actual runtime implementation ?

Maybe Florian and other Augsburg U. contributors have some input from their JWT Simulator experience on how to tread the line between devtime and runtime when "executing" an EMF workflow model.

Simplifying parameters is good.

A simple way to map a JWT model to your model would be : CompositeWorkflowComponents correspond with JWT StructuredActivityNode, and custom WorkflowComponent extension implementations will be the forecoming JWT Action extension (your endeavours are my inspiration on this side ;). I think this should be straightforward and powerful enough for you to use. Another, more powerful but more complex, would be to use pattern detection strategy like in BPEL generation (see below).

Since your model is EMF, you could use ATL to implement the transformation we've talked about in your jwt2mwe transformation plugin. Mickael has just written a doc about ATL here : http://wiki.eclipse.org/JWT_Transformations#About_ATL .


Finally, some "philosophying" about your workflow semantics (I mean how the engine decides which next WorkflowComponent is must run) and how it matches with JWT.

From what I've read, your workflows are mainly recursive compositions of CompositeWorkflowComponent and custom WorkflowComponent extension implementations, and execution of a given Composite is governed by its strategy parameter (XxxWorkflowOrchestrator). This gives it a definitive bloc-oriented, bpel-like, recursive orchestration feel.

It is quite different from the JWT metamodel, which is rather an oriented graph (node and transition -oriented). Anyway Augsburg U. has already generated BPEL from JWT (and there will be other JWT to BPEL mappings in the future as well) so the semantics and execution paradigms should map well with yours as well. The bottom line is we're very committed to also support tooling for orchestration and BPEL-like processes (we'd even be open to add another, orchestration-minded native format to the JWT suite, with optimal transformation support).

For now there are no conditional transition in your model. I guess it will appear in a ConditionalWorkflowOrchestrator, as well as other types of transitions.

Finally, note that the JWT native metamodel has a better support of usual workflow patterns (as defined at workflowpatterns.org ), while yours has a better support of orchestration concepts and strategies, such as loops.

Marc
Comment 20 Bryan Hunt CLA 2008-05-20 00:42:42 EDT
Marc,

Thanks for the feedback.  Your understanding of the design is spot-on.

Keeping the runtime state information as part of the workflow model seems to be the simplest design.  The downside is, as you pointed out, that it pollutes the design-time model.  I would love to keep the design-time model separate from the runtime model, but I don't see a clear way to do this without duplicating a lot of information and making the implementation complicated.  Ideas on this are welcome.

Consider the following use-case:  A workflow starts executing unattended, and somewhere in the middle say after step 4, an error is encountered.  The workflow is persisted with its state information.  Sometime later, a user inspects the failing workflow, fixes the error, and re-submits the workflow for execution.  The workflow needs to be able to start execution from where it left off.  It is possible for the original workflow model to have changed between the time the workflow originally executed and the time it was re-run.  The result of a workflow execution must be reproducible at a later point in time.  This is one of the primary use cases that's driving the design, and the ability to persist the model with it's state information.

Another interesting use-case is the ability for an AE to create a standard workflow that can then be customized by a user maybe using a specialized editor.

I've been considering how to do conditional transitions, and I think it will work as part of the orchestration strategy.  The interesting (hard) part will be the ability to view the workflow as a connected graph.  It seems fairly straight-forward to go from a connected graph to a composite model, but not so easy the other way around.  Where do you draw the boundaries?  I wonder if some sort of annotation would work?

I think the next work items are a better state model, re-run policy, and conditional transitions.  I'm going to dwell on these a bit, and maybe a fresh perspective will inspire a creative solution.

Comment 21 Ed Merks CLA 2008-05-20 08:28:30 EDT
I suppose one approach to the separation is kind of a decorator model in much the same way that the GenModel is a decorator for the Ecore model containing all the information that's not intrinsically part of the model (i.e., information that is needed to support a dynamic instance of the model) but rather information that will help direct how code is generated for the model.  I imagine that would certainly complicate the design significantly...
Comment 22 Bryan Hunt CLA 2008-05-20 08:42:30 EDT
One idea that occurred to me this morning to deal with the currentState would be to make that reference read-only.  However, I seem to recall that EMF has a problem with de-serialization when your attributes and references are read-only.  Ed?

A design similar to the ecore / genmodel is basically what I was referring to in my comments on separating the design-time information from the runtime information, and that design point being complicated.  I wonder if this issue might drive EMF enhancements?
Comment 23 Bryan Hunt CLA 2008-05-20 08:46:45 EDT
Another idea I just had would be to maybe store the currentState in the WorkflowContext.  I could use a Map with the WorkflowComponent as the key.
Comment 24 Ed Merks CLA 2008-05-20 08:50:52 EDT
To deserialize, the feature must be changeable reflectively, but EMF does support suppressing accessors from the API so you could suppress the set method from the interface to make it difficult though not impossible to change the value.

The GenModel supports methods like reconcile() to automatically update itself relative to the latest state of the underlying Ecore model.  It's all relatively simple, but of course not as simple as just a single model.  

It does seem better to me to separate the runtime model from the design time model, even if it does complicate the overall picture somewhat...

The mapped approach is effectively equivalent to a decorator model.  I.e., the key references the model being decorated and the value is the decorating information. 
Comment 25 Bryan Hunt CLA 2008-05-21 00:19:25 EDT
Created attachment 101188 [details]
EMF workflow model

Renamed the orchestrators to OrchestrationStrategy.  The current state is now modeled using the state pattern, and stored in the WorkflowContext.  I added a WorkflowStateResolutionStrategy for computing the state of a composite.  The default implementation is to pick the first non-successful state; otherwise return success.
Comment 26 Bryan Hunt CLA 2008-05-21 00:20:01 EDT
Created attachment 101189 [details]
Sample workflows

Updated the sample workflow for the model changes.
Comment 27 Bryan Hunt CLA 2008-05-25 14:10:53 EDT
Created attachment 101896 [details]
EMF workflow model

I've repackaged the model separating it into design-time, runtime, and orchestration packages.  I've added a WorkflowComponentOrchestrationStrategy that controls the execution of the component.  ConditionalWorkflowComponentOrchestrationStrategy extends this, and provides for conditional execution of the component.  This mechanism also allows me to provide a re-run policy based on the current state of the component.  I think the majority of the modeling is now complete.

Ed,

I want to start working on unit tests next and would like to use JUnit 4.4 with the Hamcrest library.  JUnit 4.4 did not make it though IP in time for 3.4, but can be easily hacked to work with 3.4

https://bugs.eclipse.org/bugs/show_bug.cgi?id=197170

It's also trivial to provide the full Hamcrest library as a plug-in.  Would there be a problem if I used these libraries, or must I stick with what's currently released?
Comment 28 Bryan Hunt CLA 2008-05-25 14:11:22 EDT
Created attachment 101897 [details]
Sample workflows

Updated for the latest workflow model
Comment 29 Bryan Hunt CLA 2008-05-26 10:16:17 EDT
Created attachment 101981 [details]
EMF workflow model

I've made some implementation changes that now completely decouples the runtime from the design-time model.
Comment 30 Bryan Hunt CLA 2008-06-01 10:51:02 EDT
Created attachment 103048 [details]
EMF workflow model

Cleaned up some code, and added JUnit tests.  

The tests are using JUnit 4.4.  Please see:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=197170

for instructions on how to replace JUnit 4.3.1 with 4.4
Comment 31 Bryan Hunt CLA 2008-06-01 10:52:51 EDT
Created attachment 103049 [details]
Sample workflows

The workflow launcher now uses URI's to locate the workflow and context.  I've updated the launcher to use URI's instead of workspace paths.  Note that using the Browse... buttons will not give you a proper URI.  I'll fix this in the next drop.
Comment 32 Bryan Hunt CLA 2008-06-03 23:19:07 EDT
Created attachment 103484 [details]
EMF workflow model

More code cleanup.  Added a required attribute to WorkflowParameter.  If a WorkflowParameter is required, and the value of the parameter is null, a WorkflowRuntimeException will be thrown.  Fixed the launcher to properly construct the URI when pressing the Browse Workspace button.  Added a Browse File System button to the launcher.
Comment 33 Peter Friese CLA 2008-06-04 07:04:43 EDT
Hi Bryan, thanks for your contributions. We are currently taking a deeper look at your code and the architectural ideas behind it and will probably come up with some questions soon. In the meantime, I'd like to take the chance to elaborate a bit on the goals of the EMF Modeling Workflow Engine (MWE for short) and the requirements that are derived from these goals.

The original purpose of the MWE is to provide a lightweight, easy-to-use way to configure and run code generator components. The documentation (http://www.eclipse.org/gmt/oaw/doc/4.3/html/contents/workflow_reference.html) states that "The oAW 4 workflow engine is a declarative configurable generator engine. It provides a simple, XML-based configuration language with which all kinds of generator workflows can be described. A generator workflow consists of a number of so-called workflow components that are executed sequentially in a single JVM."

I have to admit that we're using the term "workflow" in a rather light-hearted way. If you have a look at what we actually need to do with MWE, you will find that the workflows we model with MWE are rather straight-forward. Have a look at the following workflows to get a hint of what we do with MWE: http://www.eclipse.org/gmt/oaw/doc/4.3/html/contents/emf_tutorial.html#emf_tutorial_generating_code, www.eclipsecon.org/summiteurope2007/ presentations/ESE2007_Model-Friese-oAWAndOCL.pdf . Let me point out a few things: all workflows are sequential (you read a model, you validate it, you transform it, you put it into the generator to generate code, you're done). As you can see from the second sample (the PDF), writing a workflow component is a straight-forward process and does not require anything moe than a Java editor.

The current implementation of MWE makes heavy use of dependency injection (thus using Java reflection) to allow for an easy way to create workflows. This approach has proven to be very versatile and allows us to assemble all kinds of component compositions. To put it short: we're quite satisfied with the runtime aspects of MWE.

There are, however, aspects of the current implementation which could and should be improved - mostly tooling-related. As you can see, the current implementation makes use of XML as serialization format which is fine. However, the XML editor we wrote is quite basic and doesn't sport the same level of user assistance as we all have become used to from JDT (or ANT). This is an area in which we surely would appreciate help from the community.

Anyway, we're evaluating your contribution and will get back to you with questions regarding your ideas these days.

Thanks again,
Peter
Comment 34 Bryan Hunt CLA 2008-06-04 08:11:35 EDT
Peter, thank you for your comments.  One thing I would like to point out is that between the extensibility of my model (see the pojo example), and the ability to provide a custom serializer, I believe I can meet all of your requirements.
Comment 35 Sven Efftinge CLA 2008-06-04 10:53:22 EDT
Hi Brian,

I think it's a good idea to start with the requirements (the user's
perspective). I've been a user of MWE (formely oAW workflow engine) for about
two years now, and so far I'm quite happy with what it does and how it works.

The main requirements for an MWE like I use it are:
 - light weight
 - convenient
 - as well eclipse independent and eclipse integrated modeling and execution
should be possible
 - good tooling
 - open and configurable

The current version does all of this. Only the tooling isn't that good yet. So
this would be an area where I think the project needs some improvements. One
could also argue that XML isn't the syntax of our dreams, but as MWE uses it in
a very non-verbose manner it isn't too bad. Maybe an additional alternative
syntax would be cool.

To be honest, I haven't fully understood all the concepts you introduced in
your approach, but modeling every workflow component up front using EMF (I
think this was the key idea) and then implementing the operations by changing
the generated code, is much more work than doing it in simple Java like one
does with MWE. It also forces me to change generated code. Neither I want to do
that nor most of my colleagues. 

The alternative (using PojoWorkflowComponent) would be the way most people use
it. Unfortunately the modeling of the PojoWorkflowComponent like it is in your
approach is very generic. All in all the model becomes less readable and harder
to write. I'm sorry, but I don't see any benefits in this approach (actually
the contrary is the case).   

One of the most important features of the current workflow engine is dependency
injection (DI), with which one can wire and compose arbitrary Java objects up
(i.e. configuring workflow components with complex service graphs). I haven't
found something like this in your current implementation. Don't you need
something like this or do you manage more complex configuration of workflow
components differently? Or am I just blind?

I noticed the discussion about whether JWT could handle what MWE does.
I think the question is not whether something could handle something, but
whether it is a good idea to do it that way.

The term 'workflow' is of course heavily overused. In the context of MWE
workflow means something different than in the context of JWT. 
In the MWE case it's just an object graph configured declaratively using DI
which is composed of Objects implementing an interface (IWorkflowEngine).
I don't want to model MWE workflows like business processes. They are just
generator configurations.

Although I don't see any needs to do a complete rework of the workflow engine,
I really would like to see it growing. Integrating your ideas and contributions
could help as long as they fit the user's needs (requirements). 
As I said, I didn't understand all the concepts included in your prototype, so
maybe we could talk about those concepts and see if they are helpful in the
context of MWE and how we could integrate them?

My 2 cents
Comment 36 Bryan Hunt CLA 2008-06-04 11:24:38 EDT
Sven, I think the piece of the picture you are missing is the combination of using the PoJoWorkflowComponent together with a custom serializer.  Combining these two would allow someone to write a declarative workflow in XML just like you have today.  The serializer would construct the necessary pieces of the EMF model into an executable workflow.  For this use case, no EMF modeling is required.
Comment 37 Ed Merks CLA 2008-06-04 11:56:58 EDT
The fact that the workflow model isn't a model seems to quite odd to me.  One would expect all the modeling technology of the modeling project to be applicable to the workflow model.  E.g., a GMF view might be a cool thing.  But as it stands, none of it is applicable...

Taking the position of "generating models is more work than hand writing code" and on top of that taking the position that "we don't modify generated code" certainly isn't a position I expect an EMF committer to take; perhaps you didn't intend to make it sound like a sweeping value judgment and I've taken it out of context but it does sound like one. Given that these are fundamental aspects in how the vast majority of EMF's users use EMF, I'm surprised to see it.  Probably I'm reading too much into the comment.

Probably questions of blindness are a bit undiplomatic.  It's important to consider that what we want personally is not always what everyone else wants so making things flexible to support different desires is often a good approach.  Here's an example of something I'd rather not support, but the community expressed their desire and put their development resource where there desires are:

  https://bugs.eclipse.org/bugs/show_bug.cgi?id=233843
Comment 38 Peter Friese CLA 2008-06-04 13:45:08 EDT
(In reply to comment #34)
> Peter, thank you for your comments.  One thing I would like to point out is
> that between the extensibility of my model (see the pojo example), and the
> ability to provide a custom serializer, I believe I can meet all of your
> requirements.
> 

Bryan, could you provide a custom serializer? We need to support a large exising user base and need to make sure that they can use the tolling (i.e. an XML editor) in the way they are used to. Having the serializer would help us evaluating whether this requirement is met.
Comment 39 Peter Friese CLA 2008-06-04 13:53:25 EDT
(In reply to comment #27)
> Created an attachment (id=101896) [details]
> EMF workflow model
> 
> I've repackaged the model separating it into design-time, runtime, and
> orchestration packages.  I've added a WorkflowComponentOrchestrationStrategy
> that controls the execution of the component. 
> ConditionalWorkflowComponentOrchestrationStrategy extends this, and provides
> for conditional execution of the component.  This mechanism also allows me to
> provide a re-run policy based on the current state of the component.  I think
> the majority of the modeling is now complete.
> 
> Ed,
> 
> I want to start working on unit tests next and would like to use JUnit 4.4 with
> the Hamcrest library.  JUnit 4.4 did not make it though IP in time for 3.4, but
> can be easily hacked to work with 3.4
> 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=197170
> 
> It's also trivial to provide the full Hamcrest library as a plug-in.  Would
> there be a problem if I used these libraries, or must I stick with what's
> currently released?
> 

Bryan, I understand that using Hamcrest has some advantages with respect to expressiveness. However, I'd rather like to avoid using unsupported versions of JUnit and adding additional libraries. It makes setting up the dev environment unneccessary complex. I'd really appreciate if you could step own to JUnit 4.3.
Comment 40 Bryan Hunt CLA 2008-06-04 23:14:32 EDT
(In reply to comment #38)
> Bryan, could you provide a custom serializer? We need to support a large
> exising user base and need to make sure that they can use the tolling (i.e. an
> XML editor) in the way they are used to. Having the serializer would help us
> evaluating whether this requirement is met.
> 

Peter, I can create an example serializer.  It may take me a week or two.  Integrating with EMF is easy, but I don't do XML parsing so it may take me some time to figure out that part.  Would you happen to have a simple xml that you would like me to use as an example and for testing?
Comment 41 Sven Efftinge CLA 2008-06-05 03:05:22 EDT
(In reply to comment #37)
> The fact that the workflow model isn't a model seems to quite odd to me.  One
> would expect all the modeling technology of the modeling project to be
> applicable to the workflow model.  E.g., a GMF view might be a cool thing.  But
> as it stands, none of it is applicable...

I don't have a problem with the four concepts a workflow is made of being technically an EMF model. Contrary, I think this would be good as we could leverage many technologies.
The point is, how it is used. I really (and I say and always said *I*) don't want to model everything up front and then change generated code. I'm fine with supporting it but so far it feels like the recommended way.

> 
> Taking the position of "generating models is more work than hand writing code"
> and on top of that taking the position that "we don't modify generated code"
> certainly isn't a position I expect an EMF committer to take; perhaps you
> didn't intend to make it sound like a sweeping value judgment and I've taken it
> out of context but it does sound like one. Given that these are fundamental
> aspects in how the vast majority of EMF's users use EMF, I'm surprised to see
> it.  Probably I'm reading too much into the comment.

Ed, sorry if I've upset you. I'ld neither generally say "generating code is more work than hand writing code" nor the other way round. It depends on the problem to solve. I always try to see what I want to do and than find the best way making use of my mental tool box (where code generation is just one tool (although a very valuable one)).

*I*'ve had some bad experiences with modifying generated code in the past, and therefore think it's bad practice (Sorry). I found that there are many other (and IMHO better) ways to integrate generated and manually written code. 
Although, I'm an EMP committer I think it should be possible to have such an opinion, shouldn't it?

> 
> Probably questions of blindness are a bit undiplomatic.  It's important to
> consider that what we want personally is not always what everyone else wants so
> making things flexible to support different desires is often a good approach.

Indeed. Maybe it's my imperfect English. I didn't what to be undiplomatic. I tried to say "I think" and "IMHO" as often as I could to make clear that everything I say of course is always "my opinion". And I'm perfectly fine with supporting approaches I personally don't need, as long as they cannot be done in a simple, yet supported manner.
Providing different ways for the same task often makes tools complicated and error prone. 
I really would like to discuss the needs (requirements) and then see if we are talking about the same requirements and if so, whether we could design something fitting all of our needs.
 
> Here's an example of something I'd rather not support, but the community
> expressed their desire and put their development resource where there desires
> are:
> 
>   https://bugs.eclipse.org/bugs/show_bug.cgi?id=233843
> 

Taking the position "The I-Pattern for interfaces is rubbish" certainly isn't a position I expect an Eclipse committer to take... just kidding :-)
I see your point.

Thanks.


Comment 42 Sven Efftinge CLA 2008-06-05 03:24:03 EDT
(In reply to comment #36)
> Sven, I think the piece of the picture you are missing is the combination of
> using the PoJoWorkflowComponent together with a custom serializer.  Combining
> these two would allow someone to write a declarative workflow in XML just like
> you have today.  The serializer would construct the necessary pieces of the EMF
> model into an executable workflow.  For this use case, no EMF modeling is
> required.
> 

Hi Brian, 

ok, so this could be handled, cool. 
I think it's indeed a very good idea to design the AST of workflow descriptions using EMF and then provide different Resource implementations to provide different syntaxes (this is what you ment by serializer, right?). Maybe we could go for a compromise where the AST is modeled in EMF and the classes to instantiate and wire it up are just Java classes. As generated EClasses are also Java classes both approaches would work.

We would come up with tooling using JDT to statically help modeling the workflows (looking up subclasses of IWorkflowComponent, as well as inspecting the setters and adders).
This way we'ld have separated things and support all of our favored ways with the same concepts.

It would help if you could come up with things you missed in MWE and what motivated you to create your own thing.

Sorry, if I was too undiplomatic in my first post.

Comment 43 Peter Friese CLA 2008-06-05 04:21:04 EDT
(In reply to comment #40)
> (In reply to comment #38)
> > Bryan, could you provide a custom serializer? We need to support a large
> > exising user base and need to make sure that they can use the tolling (i.e. an
> > XML editor) in the way they are used to. Having the serializer would help us
> > evaluating whether this requirement is met.
> > 
> 
> Peter, I can create an example serializer.  It may take me a week or two. 
> Integrating with EMF is easy, but I don't do XML parsing so it may take me some
> time to figure out that part.  Would you happen to have a simple xml that you
> would like me to use as an example and for testing?
> 

Bryan, as an example you could use the workflow definitions I provided in comment #33: 
http://www.eclipse.org/gmt/oaw/doc/4.3/html/contents/emf_tutorial.html#emf_tutorial_generating_code and 
www.eclipsecon.org/summiteurope2007/presentations/ESE2007_Model-Friese-oAWAndOCL.pdf

Comment 44 Peter Friese CLA 2008-06-05 04:25:39 EDT
(In reply to comment #42)
> It would help if you could come up with things you missed in MWE and what
> motivated you to create your own thing.

+1. I'd like to understand what the particular benefits of your design are. I am *not* talking about why it might be a good idea to use EMF, but instead would like to understand what you are aiming at. Do you intend to provide a better tooling / tighter integration with other Eclipse projects like JWT / more flexible approach to workflow modeling / use MWE as an execution engine for business workflows?

Comment 45 Ed Merks CLA 2008-06-05 07:35:48 EDT
We actually had alternative ways to avoid modifying generated code before we came up with the JMerge approach.  That approach involved a pair of interfaces, generated and user modifiable, and a pair of classes, again, generated and user modifiable.  The approach was bloated, both in terms of files and in terms of extra byte code; even an empty class or interface leads to very significant overhead. It was also conceptually more complex and was a highly artificial pattern, i.e., not anything like how you'd design it by hand.  Ultimately the approach was abandoned for all these reasons, and a few die hard purists who believe generated code should not be touched weren't so happy about that.

Of course some people will always feel that generated code shouldn't be touched and perhaps not even committed to their repository.  They're entitled to their opinion, but generally change their opinion over time since most tools can't produce 100% satisfactory results.  Given I've been working this way for the last seven years and have never had a bad experience, I'd be curious about the nature of the bad experiences.  Eclipse keeps a history so even overwriting your changes, should you forget to remove @generated from a changed method is easily recoverable.  That's even more the case when you keep your code in a repository. Using the approach of renaming the generated method to *Gen and calling it, you can even ensure the future regenerated changes are picked up.  Of course I can see that actually changing the body of a method and removing @generated means you'll not pick of enhancements in the future, so definitely there are some disadvantages, although if the changes are merely to implement an EOperation in Java, there's not going to be changes in the future.  Of course it's possible to write an operation as an annotation on the operation as well; it's good to keep the purists happy too. :-P

In any case, everyone is definitely entitled to their opinion though I will always argue strongly with anyone who says modifying generated code is just generally a bad practice.  It's one of the pillars that has made EMF successful so if it's bad practice, it's one that has proven highly valuable and broadly appealing.

Touche on the "I-pattern" jibe. :-P Hehehe.  I do think it's an extremely unfortunate choice and I noticed that SWT didn't choose it either...

So sorry for the harsh criticism. I like to see the community function well where everyone's opinions are respected and where folks consider carefully what it's like to be at the receiving end of their commentary.  It's very hard to foster a climate of collaboration since people can and will have many legitimate differences of opinion.  In the ideal world, those differences lead to a diverse community that supports the diverse usage patterns of the users.  It's definitely very constructive to find out what Byran's design philosophy is and compare that to what's driven the project so far.

Do you guys imagine it might be possible to design a syntax other than XML for a workflow?  I guess it needs to be extensible although I could imagine supporting some type of generalized name/property syntax in the base grammar.  I'm a bit sick of XML pretending to be a human-readable syntax and I know you folks are doing some very cool things in that domain.  A workflow language with a nice human readable syntax, a high end editor, perhaps including graphical views of the flows would be pretty cool in the long term.

Did you guys ever write an XML Schema for the XML syntax?  That would certainly help make it clear the intended model of the syntax and what needs to be parsed and printed...
Comment 46 Sven Efftinge CLA 2008-06-05 08:56:24 EDT
> well; it's good to keep the purists happy too. :-P

Yes, and I'm a happy purist, because I could solve the problem thanks to the mentioned EAnnotation.

> 
> In any case, everyone is definitely entitled to their opinion though I will
> always argue strongly with anyone who says modifying generated code is just
> generally a bad practice.  It's one of the pillars that has made EMF successful
> so if it's bad practice, it's one that has proven highly valuable and broadly
> appealing.

IMHO, EMF's success in the modeling world is not based on it's generation capabilities but on the Ecore model, it's reflection layer and all the cool technologies and concepts around it (resource, validation, transaction, etc.).
The generator is useful if you want to write Java against models. In the context of code generation (at least with most generation and transformation languages) dynamic EMF is absolutely sufficient, as the languages map everything to Ecore's reflection layer no matter if it's a dynamic EObject or not.

Of course there are also cases where you want to program Java against the models and therefore the generator is cool and very important. It's just not the main reason *I* use EMF.

regarding JMerge: It's indeed primarily a user problem. I've forgotten to remove the @generated tag so many times. Although I could reproduce the code in most cases those experiences scared me somehow... In addition I have to version generated code which causes merge conflicts, the imports are not updated, elements removed from an ecore model have to be removed from the code base manually and finally JMerge works for Java only. 

> 
> Touche on the "I-pattern" jibe. :-P Hehehe.  I do think it's an extremely
> unfortunate choice and I noticed that SWT didn't choose it either...

Yes, the things we program against should be free of technical pre- or suffixes. Anyway, the 'I' is no problem for me because it's short.

> 
> So sorry for the harsh criticism. I like to see the community function well
> where everyone's opinions are respected and where folks consider carefully what
> it's like to be at the receiving end of their commentary.  It's very hard to
> foster a climate of collaboration since people can and will have many
> legitimate differences of opinion.  In the ideal world, those differences lead
> to a diverse community that supports the diverse usage patterns of the users. 
> It's definitely very constructive to find out what Byran's design philosophy is
> and compare that to what's driven the project so far.

Yes, it's important to make the different points clear first.
This might sound a bit unfriendly sometimes (it's never meant personally) but in the end we may all know what we are talking about. 

> 
> Do you guys imagine it might be possible to design a syntax other than XML for
> a workflow? 
> I guess it needs to be extensible although I could imagine
> supporting some type of generalized name/property syntax in the base grammar. 
> I'm a bit sick of XML pretending to be a human-readable syntax and I know you
> folks are doing some very cool things in that domain.  A workflow language with
> a nice human readable syntax, a high end editor, perhaps including graphical
> views of the flows would be pretty cool in the long term.


Of course. We've been thinking about form based, graphical and alternative textual syntaxes (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=218806).
I think the goal is to make it easy to combine different syntaxes for EMF based languages in general by combining GMF, TMF and other technologies. As you know we're currently working on the TMF part.
MWE will be one of our first applications for it. Still we need to support the current user base, but that shouldn't be much of a problem in this case.


> 
> Did you guys ever write an XML Schema for the XML syntax?  That would certainly
> help make it clear the intended model of the syntax and what needs to be parsed
> and printed...

It's not possible because we don't use XML in it's generic fashion. Instead of writing:
...
<parameter name="foo">
 <bean class="foo.Bar">
   <parameter name="foo" value="bar"/>
   <parameter name="nested">
       <bean class="foo.Bar2">
           <parameter name="stuff" value="apa"/>
       </bean>
   </parameter>
 </bean>
</parameter>
...

where you could of course come up with a schema declaring 'parameter' and 'bean'
we write
...
<foo class="foo.Bar" foo="bar">
   <nested class="foo.Bar2" stuff="apa"/>
</foo>
...

As you see, we use just the syntax of XML (the decision was made in order to not scare users with yet another syntax). We tried hard to make it as non-verbose and readable as possible.
Comment 47 Bryan Hunt CLA 2008-06-12 00:47:12 EDT
Created attachment 104614 [details]
EMF workflow model

Added the ability to read a declarative workflow xml file and execute the workflow.  I made a bunch of shortcuts with the xml parser so it won't handle everything someone might dream up, but it's good enough to demonstrate the capability.  I've included a launch configuration to run a declarative workflow.  The launch takes one argument which is the fully qualified path to the workflow.  The supplied launch specifies the argument as /tmp/workflow.xml
Comment 48 Bryan Hunt CLA 2008-06-12 00:48:29 EDT
Created attachment 104615 [details]
Sample declarative workflow

Here is a sample declarative workflow.  When executed, it will simply dump the parameter values.
Comment 49 Sven Efftinge CLA 2008-06-12 03:30:29 EDT
Hi Brian

Could you please tell us what your specific requirements are? 
What motivated you to implement your own framework?
We won't just replace the current code base with yours, so if you want to participate we should talk about requirements first and then see how MWE could handle them or whether we should introduce new concepts, etc..

Btw.: the example you posted still doesn't contain any DI stuff.
Comment 50 Bryan Hunt CLA 2008-06-12 08:58:45 EDT
Here are some of my key requirements.  I probably can't explain why I need these requirements without disclosing confidential information, so I'm just going to list the requirements.

The workflow model and runtime must be:
* Lightweight
* Easily persisted
* Transportable to a distributed computing environment for execution
* Capable of execution of where it left off in the event of a component failure
   - Successful components must not be re-executed
* Capable of extending the functionality of parameters
   - Simple key = value pairs are not sufficient
* Capable of executing components in parallel
* Capable of executing components conditionally
* Capable of extending the possible execution result states
* Capable of providing a rich editor for both the workflow model and parameter values
   - I think GMF might fit nicely for a workflow editor
* Capable of specifying parameter values separate from the workflow model
* Capable of providing different algorithms for determining the final execution state of a composite

While this is not a requirement, IMHO, a project that is part of EMFT should be based on EMF.
Comment 51 Sven Efftinge CLA 2008-06-12 09:53:40 EDT
Thanks, for giving some insights. I can of course understand that you're not able to tell us details about your project.
Please find my 2cents inlined.

> The workflow model and runtime must be:
> * Lightweight

+1
Although they may be different definitions of what makes a piece of software lightweight, I also like to have things as simple as possible.

> * Easily persisted

+1 (You're talking about workflow descriptions, right?)

> * Transportable to a distributed computing environment for execution

Do you mean the description, of the actual workflow component tree?
Note, that we distinct between the AST of a workflow description and the tree which is instantiated based on such a description.
While the AST indeed should and will be based on EMF the latter shouldn't.
Instead it is just an arbitrary Java object graph instantiated via dependency injection. The language and the DI container, doesn't even know about WorkflowComponent.
Of course, it should be and is possible to use Java classes, which are based on EMF (i.e. generated by EMF).

As the AST will be based on EMF, we're able to reuse remoting technology based on EMF. Would that fit the requirement?

> * Capable of execution of where it left off in the event of a component failure
>   - Successful components must not be re-executed

What if a failure is based on a previous component making a fault (e.g. wrong model transformation, corrupting the model)?

> * Capable of extending the functionality of parameters
>   - Simple key = value pairs are not sufficient

Yes, this is what dependency injection does.

> * Capable of executing components in parallel

+1

> * Capable of executing components conditionally

+1 (We already have that, but it could of course be bit more sophisticated ;-))

> * Capable of extending the possible execution result states

Could you please elaborate on this? 
What is an 'execution result state'?

> * Capable of providing a rich editor for both the workflow model and parameter
values
>   - I think GMF might fit nicely for a workflow editor

There are definitely a lot of people who would like to have a graphical modeler for workflows. Maybe this would be something you want to contribute to the project once we have the EMF based AST?

> * Capable of specifying parameter values separate from the workflow model

You mean passing external parameters into a workflow and using *.properties files? Is the current solution in MWE sufficient?

> * Capable of providing different algorithms for determining the final 
> execution state of a composite

Could you please explain this? 
What is an 'execution state'?
Is it a new concept you'ld like to introduce, which states whether a workflow component were executed successfully or not?
Is the idea to get an execution state tree as a result of an execution?

thanks,
Sven
Comment 52 Sven Efftinge CLA 2008-06-19 06:16:29 EDT
Hi Brian,

we'd a telephone call on Monday, and I promised to come up with a detailed description of what our vision of MWE is and how MWE handles your needs.
This is what I've written so far : http://wiki.eclipse.org/MWE_The_Big_Picture

First of all, I'ld like to say, that I found some of the concepts you introduced very interesting. Especially the ExecutionStatus and the possibility to execute workflows in parallel are great additions. 

During the call I already mentioned that it won't be much of a problem to instantiate your model using our di-language.

A description of your example model would look like this (I already wrote a test to ensure it works):

  WorkflowCompositeComponent {
    components = MessageGenerator {
      parameters += :output {
        type	 = "java.lang.String" 
        name	 = "OutputMessage" 
        description	= "Output message"
      }
    }
    components = LogMessage {
      parameters += :input {
        type     = "java.lang.String" 
        name     = "InputMessage"   
        description = "Input message" 
        connection  = :con {
          output = output 
          inputs += input
        }
      }
    }
    compositeOrchestrationStrategy = SerialWorkflowOrchestrationStrategy {}
    connections += con
    stateResolutionStrategy = {}
  }

 (Note that this is just the textual syntax. As there is an EMF model under the hood you could of course use other syntaxes as well. Also note that the textual editor is based on Xtext 2.0 (currently in development under TMF) and will provide all kinds of nice tooling (code completion, validation, etc.))

As the di-language should remain independent of any runtime model concepts in order to support alternative runtime models, it's the job of the runtime model designer to ensure that configurations are convenient to edit and read for the user. Hopefully you're able to tweak the model a bit in order to improve that (see http://wiki.eclipse.org/MWE_The_Big_Picture for informations on how to do it).

Hopefully the descriptions I made are understandable and that there are not too many errors in it.

Thanks,
Sven

Comment 53 Bryan Hunt CLA 2008-06-19 21:17:25 EDT
(In reply to comment #52)
> As the di-language should remain independent of any runtime model concepts in
> order to support alternative runtime models, it's the job of the runtime model
> designer to ensure that configurations are convenient to edit and read for the
> user. Hopefully you're able to tweak the model a bit in order to improve that
> (see http://wiki.eclipse.org/MWE_The_Big_Picture for informations on how to do
> it).

Sven,

Could you please elaborate a bit more on this comment.  I'm not currently understanding your concern here.

On a different topic ... in your description of the Runtime Workflow Model, you mention that a component should have optional life cycle methods.  Did you have an API in mind for this?  The IWorkflowComponent API in my proposal was created to illustrate how the model might interface to a POJO.  If you have an API, I'd like to see if I can get it to work with my proposed model.  

My IWorkflowComponent example also exposes the concept of workflow execution state to the POJO.  Do you think this would be desirable, or overly complicating the interface to the POJO?  I think this same question is also valid for the parameters.  Should the POJO see the parameters directly as part of the context, or just see the result of calling setter methods on the POJO?
Comment 54 Bryan Hunt CLA 2008-06-29 11:05:23 EDT
Created attachment 106078 [details]
EMF workflow model

Workflow parameter values are now modeled as a WorkflowParameterValue instead of an EJavaObject.  Using a java Object was going to be problematic with respect to serialization.  Modeling the value as an EMF object allows for type specific extensions and moves any custom serialization to the extensions.  I've created extensions for all of the java primitives and String.
Comment 55 Ed Merks CLA 2008-06-30 07:05:11 EDT
Brian, I've not looked at the specifics of your latest patch but the comments make me think about the fact that SimpleAnyType acts as a wrapper for data type values to make them function where an EObject is required.  Perhaps you want a parameter to be simply EObject to allow any EObject and when you need to pass a data value, you'd create an instance of SimpleAnyType.  Of course I could be completely missing the boat.
Comment 56 Bryan Hunt CLA 2008-06-30 09:25:05 EDT
Ed, thanks for your comments.  SimpleAnyType may be exactly what I'm looking for.  I'll check into this feature.
Comment 57 Sven Efftinge CLA 2008-06-30 10:19:44 EDT
Hi Brian,

sorry for the delay, I've been to a conference and therefore didn't have the time to reply earlier.

Please find my comments inlined.

(In reply to comment #53)
> (In reply to comment #52)
> > As the di-language should remain independent of any runtime model concepts in
> > order to support alternative runtime models, it's the job of the runtime model
> > designer to ensure that configurations are convenient to edit and read for the
> > user. Hopefully you're able to tweak the model a bit in order to improve that
> > (see http://wiki.eclipse.org/MWE_The_Big_Picture for informations on how to do
> > it).
> 
> Could you please elaborate a bit more on this comment.  I'm not currently
> understanding your concern here.

A simple example:
Let's say you want to have a parallel execution of workflow components.
With the current API, it's necessary to configure a workflow component with a strategy. The code/model looks something like this:

WorkflowCompositeComponent {
    compositeOrchestrationStrategy = ParallelWorkflowOrchestrationStrategy {}
    ... components
}

One might find the following notation a bit more "intentional":

Parallel {
   ...components
}

To make this possible with the MWE-DI language one has different possibilities:

1) register a custom factory, creating the readily configured WorkflowCompositeComponent for the name 'Parallel'

2) write a class with name 'Parallel' having the needed semantics (e.g. extending WorkflowCompositeComponent and have the ParallelWorkflowOrchestrationStrategy pre-configured).

This is just one instance, of how you one can improve the descriptiveness of a workflow description (other possibilities are described in http://wiki.eclipse.org/MWE_The_Big_Picture)

> 
> On a different topic ... in your description of the Runtime Workflow Model, you
> mention that a component should have optional life cycle methods.  Did you have
> an API in mind for this?  The IWorkflowComponent API in my proposal was created
> to illustrate how the model might interface to a POJO.  If you have an API, I'd
> like to see if I can get it to work with my proposed model. 

The current API is defined by the WorkflowComponent interface, which has basically two life cycle methods (checkConfiguration() and invoke())
 
> 
> My IWorkflowComponent example also exposes the concept of workflow execution
> state to the POJO.  Do you think this would be desirable, or overly
> complicating the interface to the POJO?  I think this same question is also
> valid for the parameters.  Should the POJO see the parameters directly as part
> of the context, or just see the result of calling setter methods on the POJO?
> 

I find the workflow execution state extremely useful, it should definitely become a part of the workflow model API (so far a workflow component throws a specific exception if it want to interrupt the workflow, but I like your solution better).
Regarding parameters: 
There are two different kinds of parameters one being workflow component specific setup configuration. This kind of configuration is handled through the DI language.
The other type are runtime parameters (e.g. a model passed from one to another component). So far WorkflowComponents communicate via slots in a WorkflowContext. 
I saw that you've introduced new concepts like connections and parameters. 
Is there a specific reason why you came up with these new things as opposed to stick with the simple WorkflowContext slots?

Comment 58 Bryan Hunt CLA 2008-07-08 21:49:59 EDT
Sven, my comments inlined below.

> A simple example:
> Let's say you want to have a parallel execution of workflow components.
> With the current API, it's necessary to configure a workflow component with a
> strategy. The code/model looks something like this:
> 
> WorkflowCompositeComponent {
>     compositeOrchestrationStrategy = ParallelWorkflowOrchestrationStrategy {}
>     ... components
> }
> 
> One might find the following notation a bit more "intentional":
> 
> Parallel {
>    ...components
> }

I agree that this textual notation is easier to read.  I was also under the impression that your work with Xtext could take a notation like this and transform it into an instance of my proposed model.  Is this not the case?

> 
> To make this possible with the MWE-DI language one has different possibilities:
> 
> 1) register a custom factory, creating the readily configured
> WorkflowCompositeComponent for the name 'Parallel'
> 
> 2) write a class with name 'Parallel' having the needed semantics (e.g.
> extending WorkflowCompositeComponent and have the
> ParallelWorkflowOrchestrationStrategy pre-configured).

I would think option 1 or something similar: create an instance of WorkflowCompositeComponent and an instance of ParallelWorkflowOrchestrationStrategy, then call setCompositeOrchestrationStrategy().  I guess I'm still not understanding where my proposed model fails in this situation.

> > 
> > On a different topic ... in your description of the Runtime Workflow Model, you
> > mention that a component should have optional life cycle methods.  Did you have
> > an API in mind for this?  The IWorkflowComponent API in my proposal was created
> > to illustrate how the model might interface to a POJO.  If you have an API, I'd
> > like to see if I can get it to work with my proposed model. 
> 
> The current API is defined by the WorkflowComponent interface, which has
> basically two life cycle methods (checkConfiguration() and invoke())

This API should be trivial to add to the IWorkflowComponent.  Do you see any problems other than the missing checkConfiguration() call?

> 
> > 
> > My IWorkflowComponent example also exposes the concept of workflow execution
> > state to the POJO.  Do you think this would be desirable, or overly
> > complicating the interface to the POJO?  I think this same question is also
> > valid for the parameters.  Should the POJO see the parameters directly as part
> > of the context, or just see the result of calling setter methods on the POJO?
> > 
> 
> I find the workflow execution state extremely useful, it should definitely
> become a part of the workflow model API (so far a workflow component throws a
> specific exception if it want to interrupt the workflow, but I like your
> solution better).
> Regarding parameters: 
> There are two different kinds of parameters one being workflow component
> specific setup configuration. This kind of configuration is handled through the
> DI language.
> The other type are runtime parameters (e.g. a model passed from one to another
> component). So far WorkflowComponents communicate via slots in a
> WorkflowContext.

If I pass a (non-serializable) Map to invoke() in IWorkflowComponent, would that work?

> I saw that you've introduced new concepts like connections and parameters. 
> Is there a specific reason why you came up with these new things as opposed to
> stick with the simple WorkflowContext slots?

Yes, in my use-case, I intend to extend WorkflowUnitOfWork to perform an interesting task (call it ExtendedUnitOfWork).  We will then directly create an instance of the workflow model using instances of WorkflowCompositeComponent and ExtendedUnitOfWork.  There may be cases when an ExtendedUnitOfWork will set the value of a WorkflowParameter that is needed by a subsequent ExtendedUnitOfWork as an input.  The connection of the output parameter to the input parameter will be explicitly modeled.  Using the name of the parameter as a key may not work as they are not guaranteed to be unique, and one ExtenedUnitOfWork is independent of the other meaning it does not care who produced the parameter value as long as it is set before execution.  It may be the case that an admin will assemble a composite from a set of existing components, and stitch the inputs and outputs using WorkflowParameterConnection.  We are also going to extend WorkflowParameter such that the value returned from the parameter is derived from the value in the WorkflowContext instead of the actual value in the WorkflowContext.  Some values in the WorkflowContext will be set by a user using a custom editor and persisted for later use with a workflow model.

Bryan
Comment 59 Marc Dutoo CLA 2008-07-09 11:37:43 EDT
Hi Bryan

Just wanted to say I've included your "custom Action" use case as a requirement for JWT metamodel extension mechanism at http://wiki.eclipse.org/JWT_Metamodel . 

Regards,
Marc
Comment 60 Bryan Hunt CLA 2008-07-10 00:50:23 EDT
Ed,  

Will I have to customize the generated editor in order to create instances of SimpleAnyType?  Also, if I use SimpleAnyType, it seems like I'd have to customize the editor in order to assign the SimpleAnyType value a String or Integer value correct?  The properties view is going to have entries for the key and value, but not the value of the value if that makes sense.
Comment 61 Ed Merks CLA 2008-07-10 05:45:05 EDT
Bryan,

I suppose you would yes, but in EMF 2.5 I'd be interested in generalizing the changes so they'd be available in any editor.  
Comment 62 Bryan Hunt CLA 2008-07-12 23:07:19 EDT
Created attachment 107263 [details]
EMF workflow model

Changed the generated editor to allow creation of children as parameter values.  It's a bit ugly, but this should make creating a workflow context much easier until I figure out SimpleAnyType.
Comment 63 Bryan Hunt CLA 2008-08-03 08:59:45 EDT
Created attachment 109014 [details]
EMF workflow model

Fixed a nasty bug in the launcher that would prevent parameter values from being found in the workflow context.  Thanks to Ed for helping me track down this problem.
Comment 64 Bryan Hunt CLA 2008-08-15 22:23:01 EDT
Created attachment 110142 [details]
Sample workflows

Updated the sample model to reflect the changed in the workflow meta-model.
Comment 65 Bryan Hunt CLA 2008-08-15 22:26:00 EDT
Created attachment 110143 [details]
EMF workflow model

Changed the WorkflowContext to use SimpleAnyType as the value container for parameter values.  Changed WorkflowParameter type attribute from EString to EDataType.  This change simplifies the model and adds the ability for a parameter value to be a modeled object.
Comment 66 Bryan Hunt CLA 2008-08-27 10:22:10 EDT
I've run across an interesting design issue, and would appreciate any community feedback.

The current design parameterizes a workflow unit-of-work by storing [parameter, value] pairs in a hash map as part of the WorkflowContext.  The value is actually wrapped inside an instance of SimpleAnyType which allows it to be a primitave, or even an EMF object.  

It occurred to me this morning that it might be very interesting if the workflow parameters could map to attributes / references in an arbitrary EMF model.  So instead of storing [parameter, value] pairs, the WorkflowContext would have a reference to an arbitrary EMF model, and the parameters would have a reference to maybe an EStructuralFeature (not exactly sure about the implementation here).  The parameter values would then be extracted using the EMF reflective API.

Should this new idea replace the existing WorkflowContext design, or should the design be more generic to allow for both?  I tend to favor the more generic design, but it's not currently obvious how to do the implementation.  It's also not obvious how I would extract a value from a Map, or even if this would be necessary.  It could be that the parameter points to the map itself, and you would have to extend the parameter to understand how to extract a value from the Map.

Your comments and suggestions are appreciated.
Comment 67 Sven Efftinge CLA 2008-08-27 10:41:45 EDT
(In reply to comment #66)

I'm not sure I get the point. But I'll try to answer anyway :-)

> The current design parameterizes a workflow unit-of-work by storing [parameter,
> value] pairs in a hash map as part of the WorkflowContext.  The value is
> actually wrapped inside an instance of SimpleAnyType which allows it to be a
> primitave, or even an EMF object.  
> 
> It occurred to me this morning that it might be very interesting if the
> workflow parameters could map to attributes / references in an arbitrary EMF
> model.  So instead of storing [parameter, value] pairs, the WorkflowContext
> would have a reference to an arbitrary EMF model, and the parameters would have
> a reference to maybe an EStructuralFeature (not exactly sure about the
> implementation here).  The parameter values would then be extracted using the
> EMF reflective API.

Configuring a workflow component with a *typed* complex value (instead of just passing in simple strings, objects etc.) is what I mean when I was talking of depenency injection.

IMHO such a feature is vital.

If you're still concentrating on designing a runtime model you don't have to care about this, as it is handled by the DI-language. just declare an EReference and you're done.

> 
> Should this new idea replace the existing WorkflowContext design, or should the
> design be more generic to allow for both?

Isn't the context about passing dynamic state from component to component where the configuration of components is a static thing?
I think we need both.


Comment 68 Hallvard Traetteberg CLA 2008-09-01 07:07:59 EDT
(In reply to comment #66)
> I've run across an interesting design issue

If I've understood you correctly, it's similar to a problem I have. In fact, my model in many respects is a process model, although the domain is user interface domain dialog.

In this domain, the data type of a value is often tied to the type of another value, e.g. a list shows data of type T* (or whatever indicates multiple values), while the selection is of type T. It's not only value types that are related, but also return and parameter values of functions.

Initially, my solution was to add parameters to my process-like dialog element class, as key/value pairs, and a special parameter-reference EClass, that may be used as the value of EReferences representing types. I was uncomfortable with this design, for several reasons:
- For the modeller, the option of inserting a type parameter was the non-typical case, and it resulted in a confusing user interface.
- When parameterizing the a model fragment, it was more natural to say that this part here actually is the same as this other part, instead of introducing a parameter and saying that both these are actually this parameter.
- I wanted dialogs to always be complete, and hence wanted to force the modeller to always fill in all parameters. In some sense, filling in a parameter is something that is done afterwards if the default doesn't suit you, and shouldn't be forced upon the user.
- Resolving the parameter-reference increased the complexity.

The solution I'm now considering is as follows:
- Instead of pointing from the point of usage (ParameterReference) to the defintion (Parameter) I only point from the definition to the point of usage (list of ParameterUsage objects, with a "path" from the container to the point of usage).
- Instantiating a parameter involves pointing the definition to the (new) value and patching the point of usage to refer to this new value. In case of containment, the latter my involve copying structure.

This scheme is simpler because it does not require modifications to the model where the parameter is used. It is more generic since it essentially describes how structures are shared, without being tied to a particular meta-model. However, it is more complex for the person defining a parameter, since she must have a better understanding of the meta-model. However, it should be possible to semi-automatically create the ParameterUsage objects, based on searches in the containment tree.
Comment 69 Bryan Hunt CLA 2008-09-01 09:26:55 EDT
(In reply to comment #67)
> Configuring a workflow component with a *typed* complex value (instead of just
> passing in simple strings, objects etc.) is what I mean when I was talking of
> depenency injection.
> 
> IMHO such a feature is vital.

I agree, and this is what I was attempting to do by using SimpleAnyType not realizing that it seems to limit you to an EDataType which rules out complex types.  Although SimpleAnyType extends AnyType which should allow complex types, but I didn't understand AnyType when I looked at it.  If anyone has a pointer to an example of using AnyType, that would be appreciated.

> 
> Isn't the context about passing dynamic state from component to component where
> the configuration of components is a static thing?
> I think we need both.
> 

The context is for passing dynamic state from component to component, and for dynamically configuring components at runtime.  The idea is that a user selects / edits a context that supplies all of the necessary parameter values to the components of a previously modeled workflow.

The current design of the WorkflowContext only allows for mapping parameters to EDataType values - meaning simple types.  I think we both agree that parameter values should be allowed to be typed complex values (EObject).  So it seems that parameters should be typed on EClassifier.

Example:

public class WorkflowParameter
{
  private EClassifier type;
  private String name;
  private String description;

  public void setType(EClassifier type)

  public Object getValue(WorkflowContext context)
}

My comment #66 takes this idea a step further.  What if the user's data was an instance of an EMF model, and the parameters mapped to an EStructuralFeature of that model.  I was thinking this would be a better way to model the parameters, but it seems there are problems with this design as well.

Using EStructuralFeature, you still need to map the instance of the object to the parameter so that it knows which object to get the value from using eGet().  So, right now, I don't see the advantage of this design over the current design assuming I can figure out how to use AnyType.
Comment 70 Bryan Hunt CLA 2008-09-01 09:29:49 EDT
(In reply to comment #68)
Hallvard, thanks for the comments.  I must admit that I didn't fully understand your description of your solution.  I'm probably not understanding your terminology which can be a very subtle thing that is easily misinterpreted.  If you have time, please take a look at comment #69.
Comment 71 Ed Merks CLA 2008-09-01 09:40:20 EDT
Bryan,

This article shows how to use AnyType.

 http://www.theserverside.com/tt/articles/article.tss?l=BindingXMLJava

You might want simply require it to be EObject, which allows AnyType or anything else, and can also use SimpleAnyType to wrap instances of EDataTypes so that they too are EObjects...
Comment 72 Bryan Hunt CLA 2008-09-01 09:50:15 EDT
(In reply to comment #71)
> You might want simply require it to be EObject, which allows AnyType or
> anything else, and can also use SimpleAnyType to wrap instances of EDataTypes
> so that they too are EObjects...
> 

Ah, I think you have triggered the right brain cells.  If the WorkflowContext maps parameters to EObject, then as you indicate, SimpleAnyType can be used to wrap simple types for storage in the map.  I think this also solves the other problems as well.  I think it's a simple matter of extending WorkflowParameter to know if it's pointing to a SimpleAnyType, complex EObject, or or an EClassifier of an EObject.

It's simple, elegant, and I like it.  Thank you Ed!
Comment 73 Bryan Hunt CLA 2008-09-01 09:54:39 EDT
(In reply to comment #72)
> problems as well.  I think it's a simple matter of extending WorkflowParameter
> to know if it's pointing to a SimpleAnyType, complex EObject, or or an
> EClassifier of an EObject.

Oops, I think I meant EStructuralFeature of an EObject and not EClassifier.
Comment 74 Bryan Hunt CLA 2008-09-01 10:26:32 EDT
Rather than extend WorkflowParameter, I think a value strategy pattern would be better.
Comment 75 Bryan Hunt CLA 2008-09-01 13:56:49 EDT
Created attachment 111429 [details]
EMF workflow model

WorkflowContext now maps WorkflowParameter to EObject.  Added WorkflowParameterValueStrategy which simply returns the EObject from the context map and WorkflowParameterSimpleValueStrategy which wraps the parameter value inside a SimpleAnyType.  Instances of WorkflowParameter must have a value strategy.
Comment 76 Bryan Hunt CLA 2008-09-01 13:57:39 EDT
Created attachment 111430 [details]
Sample workflows

Updates corresponding to the new workflow model
Comment 77 Hallvard Traetteberg CLA 2008-09-01 15:50:42 EDT
(In reply to comment #70)
> Hallvard, thanks for the comments.  I must admit that I didn't fully understand
> your description of your solution.

I'll try again. In my previous model, I had a Type interface and specific Type implementations, e.g. ClassType, ListType, including a TypeParameterReference class. The latter could be used to refer by name to a TypeParameter (and its value) of a containing EObject. Code that traversed structures containing the Type objects would need to detect TypeParameterReference and lookup the real TypeParameter value.

The advantage of such parameters in general, is that there is a single place (the TypeParameter's value) to change the value of several references (the value denoted by the TypeParameterReference). In my case, the abstract description of a listbox would contain a TypeParameter T and two references List<T> and T, for the output and input types of the listbox. By setting T to a specific value, like String, you would get a listbox specific for Strings.

There are several disadvantages to this approach, in particular that code everywhere needed to be aware of the mechanism and that it was cumbersome to extend it to other type than Type.

The alternative approach (which I tried to explain) is to discard the TypeReference class, and instead extend the TypeParameter objects to include a list of "paths" to every place where there used be a TypeReference. So, when the TypeParameter's value is changed, it may patch the contained structure to refer directly to the new value. In the example, the listbox would be modeled by List<Object> and Object, for output and input, respectively, with no reference to the TypeParameter. The TypeParameter object would include enough information to locate the references to Object inside the structure and when the TypeParameter's value is set to String, it would replace Object with String.

In general, the TypeParameter needs to be able to navigate to all the relevant contained EObjects and the EStructuralFeature that needs to be set (a bit similar to how an EMF XMI resource uses id fragments, by the way). It shouldn't be too difficult to make TypeParameter lookup its value in other structures and react to changes at this other location.

Hallvard
Comment 78 Bryan Hunt CLA 2008-09-28 10:39:06 EDT
Created attachment 113684 [details]
EMF workflow model

Code cleanup
Comment 79 Bryan Hunt CLA 2008-09-28 10:40:11 EDT
Created attachment 113685 [details]
Sample workflows

Updates for corresponding changes to the workflow model
Comment 80 Bryan Hunt CLA 2008-11-30 21:13:09 EST
Created attachment 119107 [details]
EMF workflow model

Customized the generated editor to allow for the creation of SimpleAnyType as values for parameters.
Comment 81 Bryan Hunt CLA 2008-12-03 20:38:40 EST
Created attachment 119452 [details]
EMF workflow model

Fixed problem with SimpleAnyType serialization
Comment 82 Bryan Hunt CLA 2008-12-04 09:47:38 EST
I've put together two screencasts on the workflow model.  The first is a presentation that explains the model, and the second is a step by step tutorial on extending and running the model.

Presentation (1024 x 768, 728 MB): http://idisk.mac.com/bhunt-Public/Workflow.mov
Tutorial (1900 x 1200, 1.17 GB): http://idisk.mac.com/bhunt-Public/WorkflowTutorial.mov

Comment 83 Bryan Hunt CLA 2008-12-11 18:48:41 EST
I've committed the core model and unit tests to CVS.

/cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.mwe/plugins/org.eclipse.emf.mwe.ewm.core
/cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.mwe/tests/org.eclipse.emf.mwe.ewm.core.tests
Comment 84 Bryan Hunt CLA 2008-12-13 14:18:51 EST
I've committed the workflow launcher with tests to CVS
Comment 85 Bryan Hunt CLA 2009-02-17 23:16:18 EST
I've committed the sample editor with some minor customizations for dealing with SimpleAnyType and the example code I'll be discussing at EclipseCon.
Comment 86 Bernd Kolb CLA 2009-05-27 10:29:11 EDT
closing