12 Replies Latest reply on Feb 28, 2008 5:20 AM by camunda

    Command facade API

    heiko.braun

      Something that's really hard to deal with is the untyped CommandService
      interface. It's not obvious what gets returned, there's a lot of casting
      involved and sometimes the result is ambiguous.

      Bernd, what do you think about a typed interface opposed to
      'public Object execute(Command command)' ?
      Could you picture a more fine grained interface? I think it would make
      it much easier to read and understand. Furthermore it would help to
      distinguish different API versions of the command facade, when JBPM
      evolves. You know we could deprecate and extend much easier.

        • 1. Re: Command facade API
          heiko.braun

          Tom wrote:

          the general idea is as follows:

          the commands are the basic blocks.
          the command executor is a generic session facade for executing commands with 1 method:

          interface CommandExecutor {
          Object execute(Command cmd);
          }

          then from that we could build specific facades like e.g.

          interface WorkflowEngine {
          ProcessInstance startNewProcessInstance(String processName);
          Token signal(Token token);
          ...
          }

          the method implementations will just create the command and send it to a command
          executor. those session facades could themselves expose the execute(command) method.
          that could be a way to keep the session facade extensible.


          once you get into these interfaces, things are hard to keep them uniform. the most
          difficulty i have on this level is hibernate's lazy loading when returning objects.
          hibernate works perfect. but what part of the object graph do we have to pre-load
          when returning objects from our persistent domain model ?

          when the execute(command) is exposed, extending commands with inheritence could also
          be used to append this eager loading inside the transaction of the command.

          similar problems and more will have to be resolved for web services. i don't think
          that we should try to target the single generic web service that matches all these
          use cases. we should try to search for a specific solution that is a good balance
          between 1) ease of use 2) coverage of the use cases and 3) ease to implement

          HTH to see the context of what we're looking for.

          • 2. Re: Command facade API
            heiko.braun

            So, from what I read the actual CommandExecutor (or CommandService) is more or less private API and the idea is to build a public one for let's say the web service interface or RMI invocations?

            This would then have clearly scoped functionality and be much easier to consume.

            • 3. Re: Command facade API
              tom.baeyens

              the command service in pvm will be a building block.

              it's up to the process languages or products to use that block and create public API's with it.

              products can choose to build a full session facade and still expose the CommandService's execute(Command) method.

              so in that context, command service can be both public and private.

              i realize that this leaves too many unresolved variables in the equation for it to be resolved. the risk is always there that we will try to build a web services solution that is too generic.

              in the solution that you work out, you'll have to make some choices anyway. but it would be good if you have an idea on how the solution fits this overall picture.

              for sure, the product specific session facades will have to be exposed as web services. if the generic command executor could be exposed as well, that would be nice to have, but i can see there are a lot of problems with that. maybe there is a ws technology in which commands can be extended to have a java-to-xml-and-back conversion.

              another approach is not to leverage the current domain model objects (ProcessInstance, Token, ProcessDefinition,...) but instead just to define a completely separate set of limited DTO's just for the web service publication. then the web service would be fixed (not very extensible). and it would be easy to implement with JAXB since the DTO's are under control of the web service.

              That would be the simplest solution that works. If we can find a solid alternative solution that is more generic, that is better. But it doesn't have to be more generic if it's going to be more complicated for the user or for the implementation.

              • 4. Re: Command facade API
                heiko.braun

                 

                it's up to the process languages or products to use that block and create public API's with it.


                OK, so we are talking about a JPDL web service facade.

                another approach is not to leverage the current domain model objects (ProcessInstance, Token, ProcessDefinition,...) but instead just to define a completely separate set of limited DTO's just for the web service publication. then the web service would be fixed (not very extensible). and it would be easy to implement with JAXB since the DTO's are under control of the web service.


                I think this is the way to go. I cannot pull the domain model because of it's dependencies and marshalling depth and furthermore I would like to keep control of the API that's getting exposed. Otherwise any change to the domain model could easily break the web service.

                Another aspect that hasn't been mentioned is is versioning [1] and evolution of the web service facade. Obviously we won't have a one shot solution.

                [1] http://www.ibm.com/developerworks/webservices/library/ws-version/

                • 5. Re: Command facade API
                  kukeltje

                   

                  I think this is the way to go. I cannot pull the domain model because of it's dependencies and marshalling depth and furthermore I would like to keep control of the API that's getting exposed. Otherwise any change to the domain model could easily break the web service.


                  This is what I tried several months ago but never finished mainly because of the jboss-ws versioning things in JBoss AS 4.0.x, 4.2 etc... I think it will work.. although I did try to keep it as close as possible to the jbpm domain objects since it just seems to fit. These same ones could be used for the rmi api as well then (imo), a win-win situation.

                  Regarding the versioning of the ws 'api', imo we should not put to much weight in that. Versioning of the rmi api, pojo api has the same issues.

                  • 6. Re: Command facade API
                    heiko.braun

                     


                    Regarding the versioning of the ws 'api', imo we should not put to much weight in that. Versioning of the rmi api, pojo api has the same issues.


                    Maybe I put it wrong. It's more backwards-compatibility I am considered about.

                    I'll commit a first draft and some WIKI docs to it, so you guys can take a look at it. Maybe actual code samples help identifying the real problems and benefits.

                    To begin with, I want to be able to drive a complete websale sample process through the web service frontend.


                    • 7. Re: Command facade API
                      heiko.braun

                      This thread has been hijacked by the discussion about the WS facade. However I would like to get back my initial concern, which is the current command API in place and especially the detyped nature of the pattern.

                      I stumbled across a quiet good explanation of my concerns here: http://fiatdev.com/2005/06/15/the-ambiguous-command-anitpattern

                      In short here's few things that are really bad with the pattern as it's used right now:

                      * Ambiguity: Both command parameters as well as return values are ambiguous. You actually need to know the command implementation and the final receiver in order to work with the API

                      * The orig pattern works best for unidirectional, fire/forget style invocations. I.e. things that should be queued. But we are looking at a broad range of uses cases here.

                      * Currently it exposes too much implementation details. If you combine this with lack of type safety, you get the perfect mess. No control what so ever.

                      From my understanding the command API should become a central piece to interact with JBPM. In that case I would reconsider this approach and maybe drop the command pattern at all and actually chose quiet the opposite solution:
                      Use well specified, strongly typed API that allows the callee to work with a blackbox JBPM.

                      • 8. Re: Command facade API
                        heiko.braun

                        I forgot one thing:

                        Class cast is evil!


                        • 9. Re: Command facade API
                          tom.baeyens

                          the command pattern is only an intermediate step towards a normal session facade interface.

                          the idea is that process languages like jPDL still could offer a session facade with normal methods, typed return values and typed parameters. these could then be implemented in terms of the command.

                          such a session facade would look like this

                          public class JpdlService extends CommandService {
                           Execution startProcess(String processName);
                           Execution signal(long executionId);
                           ...
                          }


                          impl would be something like this

                          public class JpdlServiceImpl extends CommandServiceImpl implements JpdlService {
                           public Execution startProcess(String processName) {
                           return (Execution) execute(new StartProcessCommand(processName));
                           }
                           ...
                          }


                          There are 2 motivations for this approach

                          1) graph retrieval.

                          A typical session facade doesn't have a way to specify how much of the returned object graph needs to be eagerly initialized. When navigating through the object graph outside of the session facade (hence outside the hibernate session scope) you can get lazy initialization exceptions.

                          By using the command pattern, users can easily extend a command, appending the eager fetching to the command.

                          2) open ended session facade

                          A bunch of commands are reusable. But if you're writing a UI as a front end for the whole engine, you want to do fetch very specific things from the facade. In that case, it might be easier to have local command classes to the UI, instead of bloating a customized session with hundreds of methods for each individual use case.

                          That is the summary of the argumentation why i came to it. I certainly acknowledge that it has it's limitations. But I didn't yet see a better alternative. (that incl a quick but incomplete scan of the post you referenced)

                          • 10. Re: Command facade API
                            ropalka

                             

                            "heiko.braun@jboss.com" wrote:

                            Use well specified, strongly typed API that allows the callee to work with a blackbox JBPM.

                            +1

                            • 11. Re: Command facade API
                              tom.baeyens

                               

                              "richard.opalka@jboss.com" wrote:
                              "heiko.braun@jboss.com" wrote:

                              Use well specified, strongly typed API that allows the callee to work with a blackbox JBPM.

                              +1


                              please indicate how you would deal with the 2 things i mentioned in case of a strongly typed session facade.

                              i refer to the graph retrieval problem and how to prevent that you get over a hundred methods in your session API.

                              • 12. Re: Command facade API
                                camunda

                                Hi!

                                Actually we developed a typed facade to jBPM in a former project as EJB3-SessionBean. The problem is, like Tom described, that you end up with too much methods/operations, so this facade got quite unhandy! After introducing the commands, I committed the code from that SessionBean to the Commands, and I like the code more now. Better structured, overwriting of commands possible, sending commands as JMS message possible... And in our Swing-Client-Framework we can easily use the Commands, and I think the most people build some kind of "infrastructure"-code around jBPM, so the untyped command is not the biggest problem...

                                But what I would vote for is that the CommandExecutor returns the Command object itself as result. Then you could include the return as attribute in the Command. The CommandExecutor can garantee to return the same Command-Class as given to him. So there is one ClassCast which cannot fail. And all the rest is typed...

                                There was a discussion on that in this forum: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=106234

                                Cheers
                                Bernd