5 Replies Latest reply on May 6, 2013 5:16 PM by kcbabo

    Context properties and attachments in bean services

    kcbabo

      Following up on three recent observations by Magesh:

      1. Bean services cannot set out/response context properties after the removal of Scope.IN and Scope.OUT.
      2. Bean services can accept an attachment, but not return an attachment.
      3. Bean references cannot access context properties or attachments for requests and replies.

       

      I think we can all agree that bean services should be able to do all three of the above.  Personally, I tend to think that using context properties in service implementations should be avoided whenever possible as a best practice, we all know there are occasions when you just have to do it.  Let's look at what machinery is in place right now for bean implementations:

       

      @Inject
      Context context
      

       

      This allows you to inject a Context reference for the current Message instance for an invocation, which provides access to the request message context and exchange context.  It does not provide access to context for the reply message.  The context instance is only valid for invocations of the bean service and is not related to "outbound" invocations via @Reference injections.

       

      @Inject
      Message message
      

       

      Message injection makes a reference to the request message available to a bean service implementation.  The reply message reference, if applicable, is not available.  Message instances used by @Reference invocations are not available.

       

      Possible solutions:

       

      #1) Add an annotation which allows Context and Message injection to be customized to point to input or output message.  It would need to support further parameterization to indicate if it applies to a reference.  This could be done by the Java type of a reference.  Examples:

       

      // Injection of out context
      @Inject @Target(message="out")
      Context context;
      

       

      // Injection of in context for reference invocation
      @Inject @Target(message="in", reference="myReference")
      Context context;
      
      @Inject @Reference
      MyReference myReference;
      

       

       

      #2) Create a bean-specific interface for accessing context and message instances.  For example:

       

      // This is the special interface 
      @Inject
      BeanSauce beanSauce;
      
      @Inject @Reference
      OtherService otherService;
      
      public Object myServiceMethod(Object stuff) {
         // Get request context
         Context inCtx = beanSauce.getInContext();
         // Get request message
         Message outMsg = beanSauce.getOutMessage();
      
        // Get request context for reference
         Context refContext = beanSauce.getInContext(otherService);
      }
      

       

      #3) Similar to #2, but don't return Context and Message from BeanSauce.  Instead, it should hide Context and Message and simply provide access to set/get properties and set/get attachments.  Advantage is that it abstracts away core API details.  Disadvantage is that it could be a pain to maintain and keep in sync with core API.

       

      Thoughts?

        • 1. Re: Context properties and attachments in bean services
          dward

          First off, I say let's leave in what we have now, and the @Injet of Message or Context just applies to the IN of the current service.  I like what we have there because it's simple, and covers most use cases.

           

          With regard to the propositions above:

           

          #1) If we go with this, perhaps we change message="in" to phase=ExchangePhase.IN (or OUT). But I'm shying away from this option anyway, because I don't like how error-prone it is to get the reference="myReference" String wrong.

           

          #2) I'm leaning toward this option, although perhaps "BeanSauce" gets renamed to something else, like "BeanExchange" (gah, "exchange" is an overloaded term, as is "context").  We should just come up with a better name.  Maybe "Scenario" or something.  ANYWAY, this option gives you full access to in and out of both message and context, as well as it relates to references, which get passed-in, which I like a lot.  The user can't really screw that up.  Granted, this injected type is an advanced usage, but I think it nicely complements the simple Context and Message (both IN) that we have today.

           

          3) I don't like this one, for the reason stated.  I don't want to have to maintain API congruency here.  Considering #2, again, is an advanced use case, just give them the darn objects!

          • 2. Re: Context properties and attachments in bean services
            dward

            I like the name BeanBox.

             

            It's extensible, in that in the future, we can add more stuff to it if we like, without having to add another injectable "thing".

            • 3. Re: Context properties and attachments in bean services
              splatch

              I think first and second scenario. We can mix qualifiers as we want:

               

              @Inject @Reference("foo")
              private Context fooRefContext;
              

               

              I remember that under my initial work on context refactor I introduced two additional qualifiers for context scopes @Message and @Exchange which could be used in bean services as well:

               

              @Inject @Exchange @Reference("bar")
              private Context barRefContext;
              
              @Inject @Message @Reference("baz")
              private Context msg;
              

               

              The missing part is phase for @Message since IN and OUT messages have other message contexts.

               

              One thing to remind, that Context supports access to two different scopes at same time (exchange & message). With that we may use one context reference to manipulate both IN and OUT message scopes. Depends on order of calls we will specify request properties or retrieve reply properties:

               

              @Inject @Reference("bar")
              private Context barRefContext;
              
              void doSomething(String name) {
                  barRefContext.setProperty("foo", "bar", Scope.MESSAGE); // sets IN message property
                  barRef.doSomethingTo(name);
                  barRefContext.getProperty("foo", Scope.MESSAGE); // gets OUT message property
              }
              

               

              I also like idea of having BeanSauce which could be a "producer template" for bean services.

              • 4. Re: Context properties and attachments in bean services
                dward

                In our meeting today, we like the name "BeanBag" better. W00t!

                • 5. Re: Context properties and attachments in bean services
                  kcbabo