I wouldn't roll my own state machine in Camel or any other application,
since that wheel has been invented already.  Why use a table when you can
utilize something like StatefulJ that will allow you to define states,
transitions, etc?  I would probably also leave your business logic outside
of camel, and just pass the body to a processor that offloads your work to
your business logic that handles the unmarshaling.  With Camel, I prefer to
route a message, and then hand off the work as fast as possible, and then
free up the routing to handle more messages.  To separate concerns, if the
action being performed is not directly related to one of the EIPs, then I
would avoid performing it with Camel.  Camel should route and mediate, as
described, and a processor can delegate this order processing that you want
to perform.  I would do something like:

from(<request endpoint>)
    .log()
    .unmarshal(<your serialized order or simply send the json/xml to the
processor in the next step>)
    .process(<order processor -- where you can process the order with your
state machine, if you want -- and return a result/status object>)
    .log();

What, exactly, do you want the state machine to be used for?  Depending on
your requirements, you could entirely eliminate the state machine and
handle it with a route that uses a Spring transaction manager and error
handling.  Have a look at the Transactional Client
<http://camel.apache.org/transactional-client.html> documentation, and also
the Transaction Error Handler
<http://camel.apache.org/transactionerrorhandler.html> documentation.  It
might also be helpful to look at the Error Handling
<http://camel.apache.org/error-handling-in-camel.html> docs.  If you
eliminate the use of a state machine and instead use transactions and error
handling, then it is less code that you have to maintain, particularly if
you decide, for some reason, to implement your own state table or state
machine.  Here is an example that is not meant to be fully complete, but to
give you an idea of what you might be able to do:

errorHandler(transactionErrorHandler().maximumRedeliveries(2));
onException(MyOrderProcessingException.class).maximumRedeliveries(2);
from(<request endpoint>)
    .transacted()
    .unmarshal().json(<your params here, see Camel Json
<http://camel.apache.org/json.html>> I would recommend JSON to avoid XML
and JAXB.)
    .process(<validation processor>)
    .process(<order creation notification processor>)
    .process(<order placement processor>)
    .process(<order completed processor>);

For better granularity, you can split up the process steps into their own
routes, which is what I would personally do.  Each phase (order creation,
order placement, and order completion, notifications, etc) would include
the error handling that you will want in your order placement chain of
operations.  These routes might be extremely simple, or they might be more
involved, depending on what you need to do for your service.  However, if
the routes are very simple, splitting these phases up into multiple routes
will make feature additions, etc, easier in the future.  These sub-routes
can be called from a main "ordering chain" route, which would be
transacted, and has an error handler to provide handling of errors that are
thrown by any of the routes that it calls.

I hope this helps, and feel free to contact me if you have any more
questions.

On Tue, Jan 9, 2018 at 3:22 AM, Imran Raza Khan <imranrazak...@gmail.com>
wrote:

> I design pseudo implementation of state machine in Apache camel like below,
> Please comment/suggest to improve design
>
>
>
> Table Contains State: (Would be populate in HashMap at start of
> Application)
>
> "STATE", "NEXT_STATE", "STATE_RESULT",       "CamelRoute"
>
>      1       ,           2           ,    1
>             ,          direct:initialValidation
>
>      1       ,          10          ,   -1                       ,
> direct:sendNotification
>
>      2       ,          10          ,    1                       ,
> direct:placeOrder
>
>      .       ,             .           ,     .                       ,
>                    .
>
>     .       ,             .           ,     .                       ,
>                     .
>
>    10      ,            0          ,     1                       ,
> direct:sendNotification
>
>
>
>
>
> Route:
>
> from("jetty:http://127.0.0.1:8383/request";)
>
> .log("Received a request")
>
> .unmarshal(jaxb)
>
> .bean(OrderStateMachine.class, "loadOrderStateFlow(${body})")
>
>                 .loopDoWhile(simple("${body.NextState} == 0"))
>
>                                 .bean(OrderStateMachine.class,
> "getNextState(${body})")
>
>                                 .toD(simple("${body.NextState}"))
>
>                 .end()
>
> .log("Request Processed");
>
>
>
> Regards
>

Reply via email to