You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by tm...@apache.org on 2011/12/16 09:18:57 UTC

svn commit: r1215056 - in /activemq/trunk/activemq-console/src: main/java/org/apache/activemq/console/command/ main/java/org/apache/activemq/console/filter/ test/java/org/apache/activemq/console/command/

Author: tmielke
Date: Fri Dec 16 08:18:57 2011
New Revision: 1215056

URL: http://svn.apache.org/viewvc?rev=1215056&view=rev
Log:
AMQ-3404: corrected PurgeCommand to correctly deal with message selectors

Modified:
    activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java
    activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java
    activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/filter/MessagesQueryFilter.java
    activemq/trunk/activemq-console/src/test/java/org/apache/activemq/console/command/TestPurgeCommand.java

Modified: activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java?rev=1215056&r1=1215055&r2=1215056&view=diff
==============================================================================
--- activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java (original)
+++ activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/BrowseCommand.java Fri Dec 16 08:18:57 2011
@@ -65,10 +65,12 @@ public class BrowseCommand extends Abstr
         "    Main browse -Vheader --view custom:MyField queue:FOO.BAR",
         "        - Print the message header and the custom field 'MyField' of all messages in the queue FOO.BAR",
         "",
-        "    Main browse --msgsel JMSMessageID='*:10',JMSPriority>5 FOO.BAR", 
+        "    Main browse --msgsel \"JMSMessageID='*:10',JMSPriority>5\" FOO.BAR", 
         "        - Print all the message fields that has a JMSMessageID in the header field that matches the",
-        "          wildcard *:10, and has a JMSPriority field > 5 in the queue FOO.BAR", 
+        "          wildcard *:10, and has a JMSPriority field > 5 in the queue FOO.BAR.", 
+        "          SLQ92 syntax is also supported.",
         "        * To use wildcard queries, the field must be a string and the query enclosed in ''", 
+        "          Use double quotes \"\" around the entire message selector string.",
         ""
     };
 

Modified: activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java?rev=1215056&r1=1215055&r2=1215056&view=diff
==============================================================================
--- activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java (original)
+++ activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/PurgeCommand.java Fri Dec 16 08:18:57 2011
@@ -16,11 +16,14 @@
  */
 package org.apache.activemq.console.command;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
 
+import javax.jms.Destination;
+import javax.jms.Message;
 import javax.management.MBeanServerConnection;
 import javax.management.MBeanServerInvocationHandler;
 import javax.management.ObjectInstance;
@@ -29,6 +32,8 @@ import javax.management.openmbean.Compos
 import javax.management.remote.JMXConnector;
 
 import org.apache.activemq.broker.jmx.QueueViewMBean;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.console.util.AmqMessagesUtil;
 import org.apache.activemq.console.util.JmxMBeansUtil;
 
 public class PurgeCommand extends AbstractJmxCommand {
@@ -52,12 +57,14 @@ public class PurgeCommand extends Abstra
         "    Main purge FOO.BAR", 
         "        - Delete all the messages in queue FOO.BAR",
 
-        "    Main purge --msgsel JMSMessageID='*:10',JMSPriority>5 FOO.*", 
+        "    Main purge --msgsel \"JMSMessageID='*:10',JMSPriority>5\" FOO.*", 
         "        - Delete all the messages in the destinations that matches FOO.* and has a JMSMessageID in",
         "          the header field that matches the wildcard *:10, and has a JMSPriority field > 5 in the",
-        "          queue FOO.BAR",
+        "          queue FOO.BAR.",
+        "          SLQ92 syntax is also supported.",
         "        * To use wildcard queries, the field must be a string and the query enclosed in ''",
-        "",
+        "          Use double quotes \"\" around the entire message selector string.",
+        ""
     };
 
     private final List<String> queryAddObjects = new ArrayList<String>(10);
@@ -86,13 +93,36 @@ public class PurgeCommand extends Abstra
                     if (queryAddObjects.isEmpty()) {
                         purgeQueue(queueName);
                     } else {
-                        QueueViewMBean proxy = (QueueViewMBean) MBeanServerInvocationHandler.newProxyInstance(createJmxConnection(), queueName, QueueViewMBean.class, true);
+                        
+                    	QueueViewMBean proxy = (QueueViewMBean) MBeanServerInvocationHandler.
+                    			newProxyInstance(createJmxConnection(), 
+                    					queueName, 
+                    					QueueViewMBean.class, 
+                    					true);
                         int removed = 0;
-                        for (String remove : queryAddObjects) {
-                            removed = proxy.removeMatchingMessages(remove);
-                            context.printInfo("Removed: " + removed
-                                    + " messages for msgsel" + remove);
+                        
+                        // AMQ-3404: We support two syntaxes for the message 
+                        // selector query:
+                        // 1) AMQ specific: 
+                        //    "JMSPriority>2,MyHeader='Foo'"
+                        //
+                        // 2) SQL-92 syntax:
+                        //    "(JMSPriority>2) AND (MyHeader='Foo')"
+                        //
+                        // If syntax style 1) is used, the comma separated
+                        // criterias are broken into List<String> elements. 
+                        // We then need to construct the SQL-92 query out of 
+                        // this list.
+                        
+                        String sqlQuery = null;
+                        if (queryAddObjects.size() > 1) {
+                        	 sqlQuery = convertToSQL92(queryAddObjects);
+                        } else {
+                        	sqlQuery = queryAddObjects.get(0);
                         }
+                        removed = proxy.removeMatchingMessages(sqlQuery);
+                        context.printInfo("Removed: " + removed
+                                + " messages for message selector " + sqlQuery.toString());
                     }
                 }
             }
@@ -101,7 +131,8 @@ public class PurgeCommand extends Abstra
             throw new Exception(e);
         }
     }
-
+    
+    
     /**
      * Purge all the messages in the queue
      * 
@@ -155,6 +186,34 @@ public class PurgeCommand extends Abstra
             super.handleOption(token, tokens);
         }
     }
+    
+    /**
+     * Converts the message selector as provided on command line
+     * argument to activem-admin into an SQL-92 conform string. 
+     * E.g.
+     *   "JMSMessageID='*:10',JMSPriority>5"
+     * gets converted into 
+     *   "(JMSMessageID='%:10') AND (JMSPriority>5)"
+     * 
+     * @param tokens - List of message selector query parameters 
+     * @return SQL-92 string of that query. 
+     */
+    public String convertToSQL92(List<String> tokens) {
+    	String selector = "";
+
+        // Convert to message selector
+        for (Iterator i = tokens.iterator(); i.hasNext(); ) {
+            selector = selector + "(" + i.next().toString() + ") AND ";
+        }
+
+        // Remove last AND and replace '*' with '%'
+        if (!selector.equals("")) {
+            selector = selector.substring(0, selector.length() - 5);
+            selector = selector.replace('*', '%');
+        }
+        return selector;
+    }
+    
 
     /**
      * Print the help messages for the browse command

Modified: activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/filter/MessagesQueryFilter.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/filter/MessagesQueryFilter.java?rev=1215056&r1=1215055&r2=1215056&view=diff
==============================================================================
--- activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/filter/MessagesQueryFilter.java (original)
+++ activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/filter/MessagesQueryFilter.java Fri Dec 16 08:18:57 2011
@@ -77,7 +77,7 @@ public class MessagesQueryFilter extends
      * @throws Exception
      */
     protected List queryMessages(String selector) throws Exception {
-        CompositeData[] messages = (CompositeData[]) jmxConnection.invoke(destName, "browse", new Object[] {}, new String[] {});
+    	CompositeData[] messages = (CompositeData[]) jmxConnection.invoke(destName, "browse", new Object[] {selector}, new String[] {});
         return Arrays.asList(messages);
     }
 

Modified: activemq/trunk/activemq-console/src/test/java/org/apache/activemq/console/command/TestPurgeCommand.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-console/src/test/java/org/apache/activemq/console/command/TestPurgeCommand.java?rev=1215056&r1=1215055&r2=1215056&view=diff
==============================================================================
--- activemq/trunk/activemq-console/src/test/java/org/apache/activemq/console/command/TestPurgeCommand.java (original)
+++ activemq/trunk/activemq-console/src/test/java/org/apache/activemq/console/command/TestPurgeCommand.java Fri Dec 16 08:18:57 2011
@@ -57,12 +57,31 @@ public class TestPurgeCommand extends Te
 
 	protected static final int MESSAGE_COUNT = 10;
 	protected static final String PROPERTY_NAME = "XTestProperty";
-	protected static final String PROPERTY_VALUE = "1";
+	protected static final String PROPERTY_VALUE = "1:1";
+	
+	// check for existence of property
 	protected static final String MSG_SEL_WITH_PROPERTY = PROPERTY_NAME
 			+ " is not null";
 
+	// check for non-existence of property
 	protected static final String MSG_SEL_WITHOUT_PROPERTY = PROPERTY_NAME
 			+ " is null";
+	
+	// complex message selector query using XTestProperty and JMSPriority
+	protected static final String MSG_SEL_COMPLEX = PROPERTY_NAME + "='" + 
+			"1:1" + "',JMSPriority>3";
+	
+	// complex message selector query using XTestProperty AND JMSPriority 
+	// but in SQL-92 syntax 
+	protected static final String MSG_SEL_COMPLEX_SQL_AND = "(" + PROPERTY_NAME + "='" + 
+			"1:1" + "') AND (JMSPriority>3)";
+
+	// complex message selector query using XTestProperty OR JMSPriority 
+	// but in SQL-92 syntax	
+	protected static final String MSG_SEL_COMPLEX_SQL_OR = "(" + PROPERTY_NAME + "='" + 
+			"1:1" + "') OR (JMSPriority>3)";
+	
+	
 	protected static final String QUEUE_NAME = "org.apache.activemq.network.jms.QueueBridgeTest";
 
 	protected AbstractApplicationContext context;
@@ -234,7 +253,7 @@ public class TestPurgeCommand extends Te
 		}
 	}
 
-	public void testPurgeCommand() throws Exception {
+	public void testPurgeCommandSimpleSelector() throws Exception {
 		try {
 			PurgeCommand purgeCommand = new PurgeCommand();
 			CommandContext context = new CommandContext();
@@ -258,4 +277,192 @@ public class TestPurgeCommand extends Te
 			purgeAllMessages();
 		}
 	}
+	
+	public void testPurgeCommandComplexSelector() throws Exception {
+		try {
+			PurgeCommand purgeCommand = new PurgeCommand();
+			CommandContext context = new CommandContext();
+
+			context.setFormatter(new CommandShellOutputFormatter(System.out));
+
+			purgeCommand.setCommandContext(context);
+			purgeCommand.setJmxUseLocal(true);
+
+			List<String> tokens = new ArrayList<String>();
+			tokens.add("--msgsel");
+			tokens.add(MSG_SEL_COMPLEX);
+			
+			addMessages();
+			validateCounts(MESSAGE_COUNT, MESSAGE_COUNT, MESSAGE_COUNT * 2);
+
+			purgeCommand.execute(tokens);
+
+			QueueBrowser withPropertyBrowser = requestServerSession.createBrowser(
+					theQueue, MSG_SEL_COMPLEX);
+			QueueBrowser allBrowser = requestServerSession.createBrowser(theQueue);
+
+			int withCount = getMessageCount(withPropertyBrowser, "withProperty ");
+			int allCount = getMessageCount(allBrowser, "allMessages ");
+
+			withPropertyBrowser.close();
+			allBrowser.close();
+			
+			assertEquals("Expected withCount to be " + "0" + " was "
+					+ withCount, 0, withCount);
+			assertEquals("Expected allCount to be " + MESSAGE_COUNT + " was "
+					+ allCount, MESSAGE_COUNT, allCount);
+			LOG.info("withCount = " + withCount + "\n allCount = " + 
+					allCount + "\n  = " + "\n");
+		} finally {
+			purgeAllMessages();
+		}
+	}
+	
+	public void testPurgeCommandComplexSQLSelector_AND() throws Exception {
+		try {
+			
+			String one = "ID:mac.fritz.box:1213242.3231.1:1:1:100";
+			String two = "\\*:100";
+			try {
+			if (one.matches(two)) 
+				LOG.info("String matches.");
+			else 
+				LOG.info("string does not match.");
+			} catch (Exception ex) {
+				LOG.error(ex.getMessage());
+			}
+			
+			PurgeCommand purgeCommand = new PurgeCommand();
+			CommandContext context = new CommandContext();
+
+			context.setFormatter(new CommandShellOutputFormatter(System.out));
+
+			purgeCommand.setCommandContext(context);
+			purgeCommand.setJmxUseLocal(true);
+
+			List<String> tokens = new ArrayList<String>();
+			tokens.add("--msgsel");
+			tokens.add(MSG_SEL_COMPLEX_SQL_AND);
+			
+			addMessages();
+			validateCounts(MESSAGE_COUNT, MESSAGE_COUNT, MESSAGE_COUNT * 2);
+
+			purgeCommand.execute(tokens);
+
+			QueueBrowser withPropertyBrowser = requestServerSession.createBrowser(
+					theQueue, MSG_SEL_COMPLEX_SQL_AND);
+			QueueBrowser allBrowser = requestServerSession.createBrowser(theQueue);
+
+			int withCount = getMessageCount(withPropertyBrowser, "withProperty ");
+			int allCount = getMessageCount(allBrowser, "allMessages ");
+
+			withPropertyBrowser.close();
+			allBrowser.close();
+			
+			assertEquals("Expected withCount to be " + "0" + " was "
+					+ withCount, 0, withCount);
+			assertEquals("Expected allCount to be " + MESSAGE_COUNT + " was "
+					+ allCount, MESSAGE_COUNT, allCount);
+			LOG.info("withCount = " + withCount + "\n allCount = " + 
+					allCount + "\n  = " + "\n");
+		} finally {
+			purgeAllMessages();
+		}
+	}
+	
+	public void testPurgeCommandComplexSQLSelector_OR() throws Exception {
+		try {
+			PurgeCommand purgeCommand = new PurgeCommand();
+			CommandContext context = new CommandContext();
+
+			context.setFormatter(new CommandShellOutputFormatter(System.out));
+
+			purgeCommand.setCommandContext(context);
+			purgeCommand.setJmxUseLocal(true);
+
+			List<String> tokens = new ArrayList<String>();
+			tokens.add("--msgsel");
+			tokens.add(MSG_SEL_COMPLEX_SQL_OR);
+			
+			addMessages();
+			validateCounts(MESSAGE_COUNT, MESSAGE_COUNT, MESSAGE_COUNT * 2);
+
+			purgeCommand.execute(tokens);
+
+			QueueBrowser withPropertyBrowser = requestServerSession.createBrowser(
+					theQueue, MSG_SEL_COMPLEX_SQL_OR);
+			QueueBrowser allBrowser = requestServerSession.createBrowser(theQueue);
+
+			int withCount = getMessageCount(withPropertyBrowser, "withProperty ");
+			int allCount = getMessageCount(allBrowser, "allMessages ");
+
+			withPropertyBrowser.close();
+			allBrowser.close();
+			
+			assertEquals("Expected withCount to be 0 but was "
+					+ withCount, 0, withCount);
+			assertEquals("Expected allCount to be 0 but was "
+					+ allCount, 0, allCount);
+			LOG.info("withCount = " + withCount + "\n allCount = " + 
+					allCount + "\n  = " + "\n");
+		} finally {
+			purgeAllMessages();
+		}
+	}
+	
+	public void testDummy() throws Exception {
+		try {
+			
+			String one = "ID:mac.fritz.box:1213242.3231.1:1:1:100";
+			String two = "ID*:100";
+			try {
+			if (one.matches(two)) 
+				LOG.info("String matches.");
+			else 
+				LOG.info("string does not match.");
+			} catch (Exception ex) {
+				LOG.error(ex.getMessage());
+			}
+			
+			PurgeCommand purgeCommand = new PurgeCommand();
+			CommandContext context = new CommandContext();
+
+			context.setFormatter(new CommandShellOutputFormatter(System.out));
+
+			purgeCommand.setCommandContext(context);
+			purgeCommand.setJmxUseLocal(true);
+
+			List<String> tokens = new ArrayList<String>();
+			tokens.add("--msgsel");
+			tokens.add("(XTestProperty LIKE '1:*') AND (JMSPriority>3)");
+			
+			addMessages();
+			
+			purgeCommand.execute(tokens);
+
+			/*
+			QueueBrowser withPropertyBrowser = requestServerSession.createBrowser(
+					theQueue, MSG_SEL_COMPLEX_SQL_AND);
+			QueueBrowser allBrowser = requestServerSession.createBrowser(theQueue);
+
+			int withCount = getMessageCount(withPropertyBrowser, "withProperty ");
+			int allCount = getMessageCount(allBrowser, "allMessages ");
+
+			withPropertyBrowser.close();
+			allBrowser.close();
+			
+			assertEquals("Expected withCount to be " + "0" + " was "
+					+ withCount, 0, withCount);
+			assertEquals("Expected allCount to be " + MESSAGE_COUNT + " was "
+					+ allCount, MESSAGE_COUNT, allCount);
+			LOG.info("withCount = " + withCount + "\n allCount = " + 
+					allCount + "\n  = " + "\n");
+			*/
+		} finally {
+			purgeAllMessages();
+		}
+	}
+	
+	
+	
 }