4 Replies Latest reply on Aug 13, 2018 12:58 PM by jbertram

    JMSQueueControl countMessages() with filter not working

    balint133

      Hi Guys,

       

      I've tried to search something on here and other places on the internet someone who has the same problem I do but I didn't find anybody so thats why I am opening this discussion. In short my problem is that the JMSQueueControl#countMessages doesn't work as I'd expect in case if I am using a filter.

       

      In more detail here is my case with some code snippet:

      I am using this queue to perform actions in the future so my messages are scheduled. To prevent a user submitting too much actions at once (I want to limit the number of active actions) and to calculate some numbers for the next action I came up with the idea to use the JMSQueueControl to count actually pending messages and prevent execution if the number exceeds the limit. I also using spring-test to write integration tests and preconfigured an embedded hornetQ to be able to test JMS functionality in my integration tests.

       

      Here is one of my non working code which submits JMS messages (not important parts are omitted)

       

      @Override
      public void upgradeBuilding(Building building, Planet planet) throws NotEnoughResourcesException {
        planet = planetRepository.findOne(planet.getID());
        final String actorID = (planet.getOwner() != null) ? planet.getOwner().getID() : null;
      
        final int currLvl = planet.getBuildingLevel(building);
        try {
         int pending = (int) planetQueueControl.countMessages(String.format("planetID='%s' AND buildingName='%s'",
         planet.getID(),
         building.getName()));
        
        final int nextLevel = currLvl + pending + 1;
      
        final long buildingTime = building.getBuildingTime(nextLevel);
        final Resources upgradeCost = building.getUpgradeCost(nextLevel);
      
         // Allocate resources
        ...
      
         // Queue action in the future
         UpgradeDowngradeBuildingAction action = new UpgradeDowngradeBuildingAction(planet.getID(),
         actorID,
         UpgradeDowngradeBuildingAction.Type.UPGRADE,
         building,
         upgradeCost);
      
        long executionTime = System.currentTimeMillis() + buildingTime;
      
        final Planet finalPlanet = planet;
         jmsTemplate.convertAndSend(JMS_DESTINATION, action, (msg) -> {
              if (actorID != null) {               
             msg.setStringProperty("actorID", actorID);     
              }
             msg.setStringProperty("buildingName", building.getName());
              msg.setStringProperty("planetID", finalPlanet.getID());
              msg.setLongProperty("_HQ_SCHED_DELIVERY", executionTime);
      
             return msg;
         });
         } catch (Exception e) {
         logger.error(e.getMessage(), e);
         }
      }
      
      
      

       

      Above when the code tries to count pending actions always gives back 0 when calling the method with a filter.

      Here is my integration test:

       

      @Test
      public void testDoubleUpdateBuilding() throws Exception {
        Planet planet = getPlanet();
      
        String buildingName = "metalMine";
        planetService.upgradeBuilding(buildingName, planet.getID());
        planetService.upgradeBuilding(buildingName, planet.getID());
      
        long messages = planetQueueControl.countMessages(String.format("planetID='%s' AND buildingName='%s'", planet.getID(),
        buildingName));
      
        Assert.assertEquals(2L, messages);
      }
      
      
      
      
      
      

       

      This test always fails, but if I give null as selector, the method returns the number of messages in the queue. Another strange thing if I am calling listMessages(null) it gives back 0 messages as well while there are 2 messages in the queue.

       

      Here is my hornetq-configuration.xml

      <configuration xmlns="urn:hornetq"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd">
      
      
        <connectors>
        <connector name="in-vm">
        <factory-class>org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</factory-class>
        <param key="server-id" value="0"/>
        </connector>
        </connectors>
        <security-enabled>false</security-enabled>
      
        <acceptors>
        <acceptor name="in-vm">
        <factory-class>org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory</factory-class>
        <param key="server-id" value="0"/>
        </acceptor>
        </acceptors>
      
        <address-settings>
        <address-setting match="#">
        <dead-letter-address>jms.queue.DLQ</dead-letter-address>
        <expiry-address>jms.queue.ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <max-size-bytes>-1</max-size-bytes>
        <page-size-bytes>10485760</page-size-bytes>
        <message-counter-history-day-limit>10</message-counter-history-day-limit>
        </address-setting>
        </address-settings>
      </configuration>
      
      
      
      
      
      
      

       

      hornetq-jms.xml:

      <configuration xmlns="urn:hornetq"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:hornetq ../schemas/hornetq-jms.xsd ">
      
        <connection-factory name="ConnectionFactory">
        <connectors>
        <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
        <entry name="ConnectionFactory"/>
        </entries>
        </connection-factory>
      
        <queue name="DLQ">
        <entry name="/queue/DLQ"></entry>
        </queue>
        <queue name="ExpiryQueue">
        <entry name="/queue/ExpiryQueue"></entry>
        </queue>
      
        <queue name="planetQueue">
        <entry name="/queue/planetQueue"></entry>
        </queue>
      
      </configuration>
      
      
      
      
      
      
      

       

      My first guess was transaction related but I've forbidden that one because why the non filtered method call gives back 2 while the filtered one gives back 0.  Has someone any idea why the count query gives back 0 messages when I am using it with a filter? Or Am I misconfigured something?