Just on a side note, will try to take a depper look at this mail later.

While I think the beanflow concept is cool and very usefull, I think there
are some design problems.
I have tried to fix http://issues.apache.org/activemq/browse/SM-439
without luck.  If you could have a look ;)

I think the main problem in beanflow is that the workflow is controlled
from the inside and not managed controlled by an engine.
This would also enable using persistence so that flows could
be used transactionally.  For example, if you want to include
the whole flow inside a transaction, you can obiously not spawn
a thread and perform a join later.  The different steps in the flow
have to be performed sequentially.

The flow could be described using annotations (so quite static)
or maybe dynamically using an injected interface which would
allow to fork / join tasks, while keeping these tasks under
the control of the engine.

Btw, I love the @Join("a and b") annotation.
I have previsouly thought to a less powerfull
 @Join(steps = { "a", "b" }),
but you could not have some magical expressions, like
  @Join("a + b + c >= 2")
which should be the same as
  @Join("quorum(a, b, c)")

:)

On 8/24/06, James Strachan <[EMAIL PROTECTED]> wrote:

Just another brainstorm; I thought we should split this thread into
two; one for POJOs & mapping to JBI/JSR 181/AnDI and another to doing
conversations/orchestration/workflow.

So we've got BeanFlow for writing POJO based workflows; I was
wondering about how we could link that to JBI POJOS (supporting JBI /
JSR 181 / AnDI annotations etc).

Here's a quick brainstorm. The basic idea is to introduce a little
POJO wrapper for an asynchronous JBI message exchange (a
request-response or one way which could take time to complete etc).
This POJO would implement the Activity interface from BeanFlow so we
could easily use it in a full workflow if desired. Then this POJO
would also be tied to a specific Destination. Also this POJO would be
injected by the container.

Many workflows only require making a single request on a number of
different endpoints - e.g. the following example talks to A, then
after thats complete, talks to B and C in parallel then when both of
those complete we talk to D. If we need to keep re-requesting services
we could reset the ExchangeActivity maybe (or just go back to using
the Destination directly).

So here's a little example...

public class MyWorkflow {

  @Endpoint("service:foo") ExchangeActivity a;
  @Endpoint("jms://activemq/foo.bar") ExchangeActivity b;
  @Endpoint("service:bar") ExchangeActivity c;
  @Endpoint("service:xyz") ExchangeActivity d;

   @PostConstruct
   public void start() {
     NormalizedMessage message = a.createInMessage();
     message.setContent(new StringSource("<hello>world!</hello>"));
     ...
     a.request(message);
  }

  @Join
   public void onJoin(Activity exchange) {
      if (exchange == a) {
        // lets fire off to be and c
        b.request(createRequestB());
        c.request(createRequestC());
     }
     else if (b.isComplete() && c.isComplete()) {
       d.request(createRequestD());
    }
}


So requests are all asynchronous and we get a join callback when any
of the exchanges (or other arbirary activities) change
(complete/fail/timeout) so we can perform whatever join conditions we
need.

I did ponder about using annotations to create methods for
'aComplete()' and 'bAndCComplete()' but it seems easier to use Java
code for boolean logic. The downside of this though is its not easily
possible to create tooling visualisations of this workflow.

We could use some kind of join language though so we could rewrite the
join logic as

@Join("a")
public void completedA() {
        b.request(createRequestB());
        c.request(createRequestC());
}

@Join("b and c")
public void completedBandC() {
       d.request(createRequestD());
}

where the  of a, b, c would resolve to properties or fields which must
return instances of type Activity from BeanFlow.

The nice thing about this use of @Join is that it would work with any
BeanFlow construct, JBI or otherwise. Then we are only really
introducing a POJO ExchangeActivity and an annotation to inject it
based on a destination URI (@Endpoint).

Am not particularly wedded to the names of ExchangeActivity and
@Endpoint but it was the best I could come up with without having too
much coffee yet. We might want to split @Endpoint into a couple of
tags as we might want to include both the endpoint URI and the type of
the request, InOut/InOnly etc.

Thoughts?
--

James
-------
http://radio.weblogs.com/0112098/




--
Cheers,
Guillaume Nodet

Reply via email to