Enhanced JMS Scheduler in ActiveMQ

Previously we added the ability toschedule delivery of Messages on the ActiveMQ broker.  To schedule amessage all you need to do is create the Message and then set some propertiesin the Message headers, simple right, and it allows for pretty much any clientto access this functionality whether it talks Openwire or Stomp.  Tomanage those scheduled message however you were limited to using the JMXconsole or the Web console, and while it nice that you can manage them thecurrent setup does prevent Stomp users from playing.  

This weekend I coded up a patch that allows you to manage your scheduledmessages much the same way to create them in the first place, by sending someMessages.  I've added support for requesting that the broker send all thescheduled messages to a destination of you choosing as well as allowing you tothen request that certain messages be deleted from the schedule, or all of themfor that matter.  Lets take a look at how it works...

First thing you probably want to do is to see what messages are scheduled, soto accomplish that you need to create a Producer that publishes on theDestination named: "ActiveMQ.Scheduler.Management".  Once that'sdone you create a new Message and set some properties and add a Reply Todestination so the scheduler knows where to send your Messages.  Then allyou need to do is process the messages with a Consumer that is subscribed tothat Reply To destination.



        Connection connection =createConnection();
        Session session =connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // Create the Browse Destination andthe Reply To location
        Destination requestBrowse =session.createTopic(ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION);
        Destination browseDest =session.createTemporaryQueue();

        // Create the "Browser"
        MessageConsumer browser =session.createConsumer(browseDest);

        connection.start();

        // Send the browse request
        MessageProducer producer =session.createProducer(requestBrowse);
        Message request =session.createMessage();
        request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
                                ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
        request.setJMSReplyTo(browseDest);
        producer.send(request);

        Message scheduled = browser.receive(5000);
        while (scheduled != null) {
            // Do somethingclever...
        }

With the above code your consumer will be able to check all the Messages thatare scheduled.  Now if you happen to have a huge number of Messagesscheduled then you probably don't want them all sent to your client, so tonarrow down the results you can add two additional properties to your requestMessage to define the time window that you are concerned with, here's thebrowse request code again with the properties added to see what is scheduledfor the next hour.

        // Send the browse request
        long start =System.currentTimeMillis();
        long end =System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1);

        MessageProducer producer = session.createProducer(requestBrowse);
        Message request =session.createMessage();
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
                                ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
        request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_START_TIME,Long.toString(start));
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_END_TIME,Long.toString(end));
        request.setJMSReplyTo(browseDest);
        producer.send(request);

Now that youhave seen how to browse the messages that are scheduled for delivery lets takea look at how to manage the scheduled Messages that you've browsed.  Eachscheduled Message that is sent to your consumer contains in it a Job Id thatcan be used to remove that scheduled Message from the Scheduler using the samemanagement destination that you used to request the browse from, here's anexample of that.  


        Message remove = session.createMessage();
        remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
               ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVE);
       remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID,
               scheduled.getStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID));
        producer.send(remove);


Here we create anew Message and assign it the remove action property and then set the Id of thescheduled using the Id from a Message that was sent to us on the browsedestination we created earlier.

If you want toremove some scheduled Messages but don't want to browse them just to find theone's you are interested in you can do so using the remove option show abovebut instead of specifying an Id you can give it a time window in which tooperate, here's an example show a remove operation requested for all scheduledMessages in the next hour. 

        long start =System.currentTimeMillis();
        long end =System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1);
  

        Destination management =session.createTopic(ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION);
 
        MessageProducer producer =session.createProducer(management);
        Message request =session.createMessage();
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
                               ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_START_TIME,Long.toString(start));
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_END_TIME,Long.toString(end));
        producer.send(request);


You can alsoremove all jobs from the scheduler with a single message, this is shown in thenext example.  


        Destination management =session.createTopic(ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION);
 
         MessageProducer producer =session.createProducer(management);
        Message request =session.createMessage();
       request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
        producer.send(request);


That's it for now.


具体实现demo请见 http://blog.csdn.net/lastinglate/article/details/78214617

你可能感兴趣的:(J2EE,拉屎挺累的)