Version 10

    JBossMQ Interceptor Example

     

    JBossMQ uses an interceptor pattern on the server that allows you change the behaviour of requests

    sent to the server.

    The interface for the requests is given by

    JMSServerInterceptor.

    That's a lot to implement, fortunately, there is a default implementation you can extend to only override

    the behaviour you are interested in JMSServerInterceptorSupport.

     

    The goal

     

    We want to make all messages sent to the server Non Persistent.

     

    The implementation

     

    This is trivial to do. The only complication is that messages are added using two different requests:

    • addMessage(...) - for simple non transactional send/publish

    • transact(...) - for send/publish in a transaction

    /*
     * JBossMQ, the OpenSource JMS implementation
     *
     * Distributable under LGPL license.
     * See terms of license at gnu.org.
     */
    package org.jboss.mq.server;
    
    import javax.jms.DeliveryMode;
    import javax.jms.JMSException;
    
    import org.jboss.mq.ConnectionToken;
    import org.jboss.mq.SpyMessage;
    import org.jboss.mq.TransactionRequest;
    
    /**
     * Makes all messages Non Persistent
     *
     * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
     * @version $Revision: 1.1.2.1 $
     */
    public class NonPersistentInterceptor extends JMSServerInterceptorSupport
    {
       public void addMessage(ConnectionToken dc, SpyMessage message) throws JMSException
       {
          makeNonPersistent(message);
          super.addMessage(dc, message);
       }
    
       public void transact(ConnectionToken dc, TransactionRequest t) throws JMSException
       {
          if (t.messages != null)
          {
             for (int i = 0; i < t.messages.length; ++i)
                makeNonPersistent(t.messages+);
          }
          super.transact(dc, t);
       }
    
       /**
        * Overrides the message to be Non Persistent
        * 
        * @param message the message
        * @throws JMSException for any error
        */
       protected void makeNonPersistent(SpyMessage message) throws JMSException
       {
          message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
       }
    }
    

     

    *Compile your interceptor and put it in a jar in server/{config-name}/lib where {config-name}

    is the jboss configuration you are using, e.g. default or all*

     

    The configuration

     

    Now we edit the server interceptor chain to include our interceptor. This can be found in

    deploy{-hasingleton}/jms/jbossmq-service.xml

     

    We simply tell the SecurityManager to invoke us rather than the

    DestinationManager. We then invoke the DestinationManager after we have modified the messages.

     

    
      <!-- ==================================================================== -->
      <!-- JBossMQ Interceptor chain configuration                              -->
      <!-- ==================================================================== -->
      <!-- To tune performance, you can have the Invoker skip over the TracingInterceptor -->
      <!-- and/or the SecurityManager, but then you loose the ability to trace and/or enforce security. -->
      <mbean code="org.jboss.mq.server.jmx.Invoker" name="jboss.mq:service=Invoker">
        <depends optional-attribute-name="NextInterceptor">jboss.mq:service=TracingInterceptor</depends>
      </mbean>
    
      <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=TracingInterceptor">
        <attribute name="InterceptorClass">org.jboss.mq.server.TracingInterceptor</attribute>
        <depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager</depends>
      </mbean>
    
      <mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=SecurityManager">
        <attribute name="DefaultSecurityConfig">
          <security>
            <role name="guest" read="true" write="true" create="true"></role>
          </security>
        </attribute>
        <attribute name="SecurityDomain">jbossmq</attribute>
    

        <!-- Here we tell the SecurityManager to invoke us rather than the DestinationManager -->

       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NonPersistent</depends>
      </mbean>
    

        <!-- Here we define our interceptor and tell it to invoke the DestinationManager  -->

      <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=NonPersistent">
        <attribute name="InterceptorClass">org.jboss.mq.server.NonPersistentInterceptor</attribute>
        <depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends>
      </mbean>
    

     

    Conclusion

    The use of the interceptor pattern in JBossMQ allows you to control how the client requests are processed.

    Allowing you to implement your own policy decisions.

     

    • Please contribute your own interceptors that may be useful to others