3 Replies Latest reply on Sep 18, 2008 9:20 AM by timfox

    Notifications over JBM core connections

    jmesnil

      As part of the management task, I'm implementing receiving management notifications over JBM core connections.

      The idea is that a Core client can subscribe to notifications by asking the server to send a message to a given destination every time a notification is triggered on the server (e.g. a queue is full, a queue is added to the server)

      - the client creates a "management message", a Core message with well-known properties:
      * the ObjectName it wants to observe
      * the destination where the notification messages must be sent (specified by the client, can be any kind of destination, more likely either a topic or a temp queue)
      - it sends the message to the server

      - the server handles the message
      * the PostOffice detects it is a management message and pass it to the management service
      * the management service creates a NotificationListener for the given ObjectName

      - Later on, when a notification is received by the listener (e.g. a queue is full)
      * the listener creates a Core message and fills it with the notifications information (who, when, what, etc.)
      * this core message is then routed by the PostOffice according to the destination set by the client

      - the client will receive the Core message and process the notification information

      So, the big idea is that a Core message is created on the /server-side/ as the result of a notification (internal to the server) and not as the result of receiving a message from a client.
      I'm not sure about the best way to create a Core message on the server.

      The ManagementService code looks like:

      // when handling a "management message"
      final SimpleString replyTo = (SimpleString)message.getProperty(ManagementMessageImpl.HDR_JMX_REPLYTO);
      boolean subscribe = (Boolean)message.getProperty(ManagementMessageImpl.HDR_JMX_SUBSCRIBE_TO_NOTIFICATIONS);
      if (subscribe)
      {
       broadcaster.addNotificationListener(new NotificationListener() {
       public void handleNotification(Notification notification, Object handback)
       {
       ServerMessage notificationMessage = new ServerMessageImpl(0);
       notificationMessage.setDestination(replyTo);
       // FIXME no hard-coded value
       notificationMessage.setBody(new ByteBufferWrapper(ByteBuffer.allocate(1024)));
       notificationMessage.putBooleanProperty(ManagementMessageImpl.HDR_JMX_NOTIFICATION, true);
       notificationMessage.putStringProperty(new SimpleString("notif"), new SimpleString(notification.getMessage()));
       try
       {
       postOffice.route(notificationMessage);
       }
       catch (Exception e)
       {
       log.warn("problem while routing a notification message", e);
       // TODO unregister the listener for the broadcaster
       }
       }
       }, null, null);
      }
      ...
      


      The code to create the notificationMessage is not correct.
      I need to use a proper message ID but, on the server-side, it is the storage manager which owns the ID sequence.
      I could inject the storageManager into the managementService to get access to its generateID() but it smells like a bad idea.
      I could create a new POJO, a ID generator, injected in both the storageManager and the managementService.

      What do you think?
      Does this make sense?


        • 1. Re: Notifications over JBM core connections
          timfox

           

          "jmesnil" wrote:
          As part of the management task, I'm implementing receiving management notifications over JBM core connections.

          The idea is that a Core client can subscribe to notifications by asking the server to send a message to a given destination every time a notification is triggered on the server (e.g. a queue is full, a queue is added to the server)

          - the client creates a "management message", a Core message with well-known properties:
          * the ObjectName it wants to observe


          What if there is no jmx server running? All this stuff should work with no JMX server too.


          * the destination where the notification messages must be sent (specified by the client, can be any kind of destination, more likely either a topic or a temp queue)
          - it sends the message to the server

          - the server handles the message
          * the PostOffice detects it is a management message and pass it to the management service


          I think it might be better to introduce a new packet on the wireformat ManagementMessage and send via that, then there's no need for special routing in the post office - it can be intercepted at the session level


          * the management service creates a NotificationListener for the given ObjectName


          This seems JMX dependent to me


          - Later on, when a notification is received by the listener (e.g. a queue is full)


          Are notifications supposed to be persisent (i.e. do they survive after the session that created them has died?)

          If not, then the listener could just be the session, and you could use the standard session send functionality to send the notification

          • 2. Re: Notifications over JBM core connections
            jmesnil

             

            "timfox" wrote:

            What if there is no jmx server running? All this stuff should work with no JMX server too.


            It does work even when there is no JMX MBeanServer (the ManagementService keeps a registry of managed resources using ObjectNames as their keys)

            "timfox" wrote:

            I think it might be better to introduce a new packet on the wireformat ManagementMessage and send via that, then there's no need for special routing in the post office - it can be intercepted at the session level


            "timfox" wrote:

            "jmesnil wrote:
            * the management service creates a NotificationListener for the given ObjectName


            This seems JMX dependent to me


            Same as above, I use a NotificationBroadcaster to keep track of notifications but it does not depend on any MBeanServer

            "timfox" wrote:

            Are notifications supposed to be persisent (i.e. do they survive after the session that created them has died?)

            If not, then the listener could just be the session, and you could use the standard session send functionality to send the notification


            I do not intend for the notifications to be persistent.
            It makes sense to move the notification handling to the session.
            But it still got the same issue: ServerSession.send() expect a ServerMessage that I need to create.


            • 3. Re: Notifications over JBM core connections
              timfox

               

              "jmesnil" wrote:

              It makes sense to move the notification handling to the session.
              But it still got the same issue: ServerSession.send() expect a ServerMessage that I need to create.


              You could just add a constructor to ServerMessage, like the ClientMessage one:

              public ClientMessageImpl(final boolean durable, MessagingBuffer body)
               {
               super((byte) 0, durable, 0, System.currentTimeMillis(), (byte)4, body);
               }
              


              And create a buffer before creating it, like is done in ClientSessionImpl::createClientMessage() but with a server message rather than a client message.

              Then call session::send directly on the server, and that will handle all the assigning of a message id etc.