1 2 3 Previous Next 39 Replies Latest reply on Apr 19, 2011 5:27 AM by henrique.malheiro

    Annotation based Action classes

    tfennelly

      With subversion lockdown at the moment, I decided to have a look at how we could improve the Action class API... make it a bit easier to use.

       

      So at the moment, to implement an Action you need to implement the ActionLifecycle interface (or one of it's derived interfaces/classes).  Configuration is done through the universally hated ConfigTree, which must be supplied via constructor.  In all... implementing an Action is quite ugly (imo).

       

      After a few hours playing, I have the following working.  You can implement an action that looks like the following:

       

      public class Action1234 {
      
          @ConfigProperty
          private File pickupFile;
          
          @ProcessMethod
          public void processMethod(Message m) {
              FileWriter writer = new FileWriter(pickupFile);
      
              // etc....
          }        
      }
      

       

      No need to implement interfaces... no ConfigTree... configuration is reflectively injected via the @ConfigProperty annotation on the bean fields/setters.

       

      The esb config for this looks just like any other action:

       

      <action name="action" class="com.acme.Action1234">
          <property name="pickupFile" value="./pickupFile.xml" />
      </action>
      

       

      It also supports @ProcessMethod implementations that take non ESB Message parameters e.g.

       

      public class Action1234 {
          
          @ProcessMethod
          public OrderAcknowledgment processOrder(Order purchaseOrder) {
              // Do your thing with the order...
      
              return new OrderAcknowledgment(....);
          }        
      }
      

       

      In the above case, the Order instance needs to be set as the ESB Message payload i.e. the action configured before this action needs to create the Order (via transformation etc) and set it as the payload on the Message instance it returns.  This Order will then get extracted from the ESB Message and passed into the processOrder method.   Likewise with the OrderAcknowledgement return val... set on the ESB Message instance forwarded to the next action in the pipeline.  All this is done using the standard MessagePayloadProxy get/set mechanism.  Would be easy enough (I think) to add marshal/unmarshal support here, for marshaling e.g. an XML message payload into java objects that can then be used as args to the @ProcessMethod - opposite on the way out.

       

      Lifecycle... initialize and destroy... add public no-arg methods and annotate them with @Initialize or @Destory.

       

      The @ConfigProperty annotation for injecting the config params was lifeted from Smooks (called @ConfigParam in Smooks).  It handles extraction of the config parameter (form the ConfigTree) and injection into the bean. Also handles all the decoding e.g. in the case above, decoding the string value into a java.io.File instance.  Handles REQUIRED and OPTIONAL config params... "choices" etc.  This removes a lot of noise from the code!!

       

      All of this was done within the confines of the current Actions, ConfigTree etc APIs.  The bean action is wrapped in a normal ConfigTree/ActionLifecycle action implementation (I currently call it BeanContainerAction).  It did require a relatively small addition to the ActionProcessingPipeline to hook in this new type of action, wrapping it in the BeanContainerAction.

       

      The @ConfigParam an lifecycle annotations could also be used on the listeners etc... thereby hiding our beloved ConfigTree from most users

        • 1. Re: Annotation based Action classes
          burrsutter

          A POJO Action (custom mediator) would be a HUGE improvement over the curent Action API.  I am all for it. :-)

           

          Another goal/benefit would be to improve automated Unit Testing (e.g. via JUnit or TestNG).

           

          Please show a mock-up of the jboss-esb.xml in the case of the Order instead of the Message example - it helps to visualize these things.

          • 2. Re: Annotation based Action classes
            beve

            This looks nice. I like!

             

            /Dan

            • 3. Re: Annotation based Action classes
              h.wolffenbuttel

              Hi Tom,

               

              Does this mean you could have more then one @ProcessMethod with differend parameters where the kind of payload will activate the right one for the job?

               

              I will illustrate: Say you have differend kinds of orders: orders-send-by-mail, orders-picked-up-at-location and express-orders. All these orders are converted by unmarshalling it from XML to Java-objects. Then the actionclass would look like:

               

               

              {code:java}
              public
              class
              HandleOrderAction{

                 @ProcessMethod

                 public OrderAcknowledgment processOrder(MailOrder purchaseOrder){
                  // Do your thing with the order...    

                   return
              new OrderAcknowledgment(....);

                 }

               


                 @ProcessMethod

                 public OrderAcknowledgment processOrder(PickupOrder purchaseOrder){


                  // Do your thing with the order...



                   return
              new OrderAcknowledgment(....);

                 }

               


                 @ProcessMethod

                 public OrderAcknowledgment processOrder(ExpressOrder purchaseOrder){


                  // Do your thing with the order...



                   return
              new OrderAcknowledgment(....);

                 }

              }


              {code}

               

              So when an expressorder is placed, the processmethod will call the method with the ExpressOrder as incoming parameter, when a mailorder is placed the method will be called with the MailOrder parameter and so on.

               

              Will this work or is this possible in any way?

               

              regards,

               

              Hans

              • 4. Re: Annotation based Action classes
                tfennelly

                Hi Hans.

                 

                Yes... this would be easy enough to do.  Of course you'd need to analyse the class and make sure there's exactly only one possible target @ProcessMethod, but that's easy.

                 

                I think it could also be possible to support automatic unmarshalling/marshalling by detecting that the target @ProcessMethod is arg is JAXB annotated.  So, if the payload was XML and the method arg was JAXB annotated, you could automatically trigger JAXB to create the objects from the payload XML.

                 

                Then, for unmarshalling other payload types (non-XML), or for unmarshalling into objects that are not JAXB annotated, or for servicing @ProcessMethods with multiple args.... you could allow unmarshalling by defining a smooks binding config on the action.

                 

                Anyway... we'll see

                • 5. Re: Annotation based Action classes
                  tfennelly

                  Hi Burr.

                   

                  Yes... obviously testing would be easier since you don't need to deal with ConfigTree... just use setters.  The @ConfigProperty can also be placed on a setter instead of the field.

                   

                  As for an example config, you'd just need an action beforehand that performs a "to-Order" transform, setting the created Order on the Message payload.

                   

                  Also, as hinted to above.... we could support auto-binding (unmarshalling).

                  • 6. Re: Annotation based Action classes
                    edgar.silva

                    Tom,

                     

                    That's is a very nice idea, I wrote a blog post in my blog about 2 years ago:

                     

                    http://ankiewsky.blogspot.com/2008/09/posos-plain-old-services-objects-in.html

                     

                    However, I had no chance to continue this job, but I vote that it could come as a good innovation for JBoss ESB

                     

                    Edgar

                    • 7. Re: Annotation based Action classes
                      bradsdavis

                      I actually would rather see some of the Action approaches @Deprecated.  Right now, there are too many ways to create an action, which leads to too many test paths for the platform, and in the future, too many upgrade paths to maintain.  Also, the lack of consistency here confuses customers when trying to decide on a "best approach".

                       

                      For example, just in the quickstarts alone, I have see the following ways to create actions:

                      Some Actions extend AbstractActionLifecycle, some implement BeanConfiguredAction, others  ActionPipelineProcessor, and still others  AbstractActionPipelineProcessor.

                      • 8. Re: Annotation based Action classes
                        kconner

                        Deprecation of other approaches, if and when that may happen, is a separate issue.  Please do not derail this discussion by taking it off on a tangent.

                         

                        Kev

                        • 9. Re: Annotation based Action classes
                          dvanbalen

                          Would this approach allow for some default action behavior? For instance, allowing the user to specify an alternate response location for the action's result. I think basic functionality like that should be included in all actions by default, rather than having to rely on each action's developer re-inventing the wheel every time.

                           

                          See https://jira.jboss.org/jira/browse/JBESB-3313 for more on the above.

                           

                          I also agree that this approach to action development, along with possibly one or two others that provide the same level of abstraction from the way messages and action configuration are implemented within the ESB, would need to be enforced as the standard methods for creating actions. Legacy actions would also need to be converted to use this approach so that issues like missing basic bahavior doesn't negatively affect future development.

                          • 10. Re: Annotation based Action classes
                            tfennelly

                            I commited what I have on this to a workspace in SVN: http://anonsvn.jboss.org/repos/labs/labs/jbossesb/workspace/tfennelly/annotated_components

                             

                            I modified the http_gateway quickstart as one example:

                             

                            In it you can see how the @ProcessMethod method is now taking multiple non ESB Message params.  The params are annotated with @BodyParam and @PropertyParam annotations (@AttachmentParam also there), which tell the ESB from where on the Message to extract those params before invoking the process method @ProcessMethod.

                             

                            @ProcessMethod
                            public String printHttpRequestInfo(@BodyParam byte[] httpPayload, @PropertyParam HttpRequest requestInfo )

                             

                            Those params can also take an explicit named location (e.g. @BodyParam("orderInfo")).  These @XParam annotations are not required.  If not present, the ESB will search the message based on param type, which is convenient but of course has the obvious "risks" that need to be kept in mind.

                             

                            An example that also included a number of configurations would be better again (see use of the @ConfigProperty annotation), but I think/hope you get the picture.

                             

                            The full FishEye changeset is http://fisheye.jboss.org/changelog/JBossESB/?cs=32847

                            • 11. Re: Annotation based Action classes
                              bradsdavis

                              Tom, perhaps we should add another annotation for where the response should be placed back into the message.

                               

                              Additionally, I think we should be able to override the default location annotations in the XML configurations.

                              • 12. Re: Annotation based Action classes
                                jtyrrell
                                @ProcessMethod should have a parameter like 
                                @ProcessMethod(name="ProcessTheOrder")
                                This would give the tooling something to look at, reference that is not just a "ProcessMethod".  What other meta data might need to be added to this tag, the gateway, listener, or is that just crazy talk?
                                • 13. Re: Annotation based Action classes
                                  tfennelly

                                  Hey Jim... and what about the name of the process method itself... is it not the "name".. seems to me that adding a name annotation would be duplicating this, no?

                                  • 14. Re: Annotation based Action classes
                                    jtyrrell

                                    But shouldn't you be able to change the name and give it a level of indirection.  That is usually good in programming.  Just a thought, and I agree the name can be the name, but what if you wanted to make it more friendly for business analysts and users.  Or the method was named poorly in the past.

                                    1 2 3 Previous Next