From 821005ab6ea662ed4304b8041e6bd5616c762cbe Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Fri, 27 Sep 2024 15:08:38 -0500 Subject: [PATCH] ARTEMIS-5075 support NOT_EQUALS op to filter some mngmnt results This commit adds support for a NOT_EQUALS operator to the management operations which already support filtering. It also adds a handful of tests for the predicate since there didn't seem to be any such tests. --- .../webapp/plugin/js/components/addresses.js | 1 + .../plugin/js/components/connections.js | 1 + .../webapp/plugin/js/components/consumers.js | 1 + .../webapp/plugin/js/components/producers.js | 1 + .../webapp/plugin/js/components/queues.js | 1 + .../webapp/plugin/js/components/sessions.js | 1 + .../predicate/ActiveMQFilterPredicate.java | 40 +++++-- .../impl/view/predicate/PredicateTest.java | 106 ++++++++++++++++++ docs/user-manual/management.adoc | 1 + 9 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/view/predicate/PredicateTest.java diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addresses.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addresses.js index 504b2a22db..b1707921ae 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addresses.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addresses.js @@ -110,6 +110,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'}, {id: 'NOT_CONTAINS', name: 'Does Not Contain'}, {id: 'GREATER_THAN', name: 'Greater Than'}, diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/connections.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/connections.js index d99754fd83..63a5225f47 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/connections.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/connections.js @@ -132,6 +132,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'}, {id: 'NOT_CONTAINS', name: 'Does Not Contain'}, {id: 'GREATER_THAN', name: 'Greater Than'}, diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/consumers.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/consumers.js index 58144361c0..ec9ab72caf 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/consumers.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/consumers.js @@ -150,6 +150,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'}, {id: 'NOT_CONTAINS', name: 'Does Not Contain'}, {id: 'GREATER_THAN', name: 'Greater Than'}, diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/producers.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/producers.js index 8ab622ea2d..66d10afa4f 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/producers.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/producers.js @@ -119,6 +119,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'} ], sortOptions: [ diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/queues.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/queues.js index ac2c264bda..ce26f728b6 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/queues.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/queues.js @@ -148,6 +148,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'}, {id: 'NOT_CONTAINS', name: 'Does Not Contain'}, {id: 'GREATER_THAN', name: 'Greater Than'}, diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sessions.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sessions.js index 3328d5a75b..eb8cb3c94e 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sessions.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sessions.js @@ -129,6 +129,7 @@ var Artemis; ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, + {id: 'NOT_EQUALS', name: 'Not Equals'}, {id: 'CONTAINS', name: 'Contains'}, {id: 'NOT_CONTAINS', name: 'Does Not Contain'}, {id: 'GREATER_THAN', name: 'Greater Than'}, diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/ActiveMQFilterPredicate.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/ActiveMQFilterPredicate.java index 80a373fb44..d742f9a67d 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/ActiveMQFilterPredicate.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/ActiveMQFilterPredicate.java @@ -23,7 +23,7 @@ import java.util.function.Predicate; public class ActiveMQFilterPredicate implements Predicate { public enum Operation { - CONTAINS, NOT_CONTAINS, EQUALS, GREATER_THAN, LESS_THAN; + CONTAINS, NOT_CONTAINS, EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN; } protected String field; @@ -32,10 +32,6 @@ public class ActiveMQFilterPredicate implements Predicate { protected Operation operation; - public static boolean contains(String field, String value) { - return field.contains(value); - } - public ActiveMQFilterPredicate() { } @@ -65,7 +61,7 @@ public class ActiveMQFilterPredicate implements Predicate { } public void setOperation(String operation) { - if (operation != null && !operation.equals("")) { + if (operation != null && !operation.isBlank()) { this.operation = Operation.valueOf(operation); } } @@ -75,6 +71,8 @@ public class ActiveMQFilterPredicate implements Predicate { switch (operation) { case EQUALS: return equals(field, value); + case NOT_EQUALS: + return !equals(field, value); case CONTAINS: return contains(field, value); case NOT_CONTAINS: @@ -104,16 +102,22 @@ public class ActiveMQFilterPredicate implements Predicate { longValue = Long.parseLong(value); } catch (NumberFormatException ex) { //cannot compare - return false; + if (operation == Operation.NOT_EQUALS || operation == Operation.NOT_CONTAINS) { + return true; + } else { + return false; + } } switch (operation) { case EQUALS: return field == longValue; + case NOT_EQUALS: + return field != longValue; case CONTAINS: return false; case NOT_CONTAINS: - return false; + return true; case LESS_THAN: return field < longValue; case GREATER_THAN: @@ -131,16 +135,22 @@ public class ActiveMQFilterPredicate implements Predicate { intValue = Integer.parseInt(value); } catch (NumberFormatException ex) { //cannot compare - return false; + if (operation == Operation.NOT_EQUALS || operation == Operation.NOT_CONTAINS) { + return true; + } else { + return false; + } } switch (operation) { case EQUALS: return field == intValue; + case NOT_EQUALS: + return field != intValue; case CONTAINS: return false; case NOT_CONTAINS: - return false; + return true; case LESS_THAN: return field < intValue; case GREATER_THAN: @@ -158,16 +168,22 @@ public class ActiveMQFilterPredicate implements Predicate { floatValue = Float.parseFloat(value); } catch (NumberFormatException ex) { //cannot compare - return false; + if (operation == Operation.NOT_EQUALS || operation == Operation.NOT_CONTAINS) { + return true; + } else { + return false; + } } switch (operation) { case EQUALS: return field == floatValue; + case NOT_EQUALS: + return field != floatValue; case CONTAINS: return false; case NOT_CONTAINS: - return false; + return true; case LESS_THAN: return field < floatValue; case GREATER_THAN: diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/view/predicate/PredicateTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/view/predicate/PredicateTest.java new file mode 100644 index 0000000000..088ff3e656 --- /dev/null +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/management/impl/view/predicate/PredicateTest.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.core.management.impl.view.predicate; + +import org.apache.activemq.artemis.utils.RandomUtil; +import org.junit.jupiter.api.Test; + +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.CONTAINS; +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.EQUALS; +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.GREATER_THAN; +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.LESS_THAN; +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.NOT_CONTAINS; +import static org.apache.activemq.artemis.core.management.impl.view.predicate.ActiveMQFilterPredicate.Operation.NOT_EQUALS; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class PredicateTest { + + @Test + public void testBasePredicateEquals() { + String string = RandomUtil.randomString(); + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(EQUALS.name()); + predicate.setValue(string); + assertTrue(predicate.matches(string)); + assertFalse(predicate.matches(RandomUtil.randomString())); + assertFalse(predicate.matches(0L)); + assertFalse(predicate.matches(0f)); + assertFalse(predicate.matches(0)); + } + + @Test + public void testBasePredicateNotEquals() { + String string = RandomUtil.randomString(); + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(NOT_EQUALS.name()); + predicate.setValue(string); + assertFalse(predicate.matches(string)); + assertTrue(predicate.matches(RandomUtil.randomString())); + assertTrue(predicate.matches(0L)); + assertTrue(predicate.matches(0f)); + assertTrue(predicate.matches(0)); + } + + @Test + public void testBasePredicateContains() { + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(CONTAINS.name()); + predicate.setValue("12"); + assertTrue(predicate.matches("0123")); + assertFalse(predicate.matches("43")); + assertFalse(predicate.matches(0L)); + assertFalse(predicate.matches(0f)); + assertFalse(predicate.matches(0)); + } + + @Test + public void testBasePredicateNotContains() { + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(NOT_CONTAINS.name()); + predicate.setValue("12"); + assertFalse(predicate.matches("0123")); + assertTrue(predicate.matches("42")); + assertTrue(predicate.matches(0L)); + assertTrue(predicate.matches(0f)); + assertTrue(predicate.matches(0)); + } + + @Test + public void testBasePredicateLessThan() { + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(LESS_THAN.name()); + predicate.setValue("12"); + assertFalse(predicate.matches("foo")); + assertFalse(predicate.matches(42)); + assertTrue(predicate.matches(0L)); + assertTrue(predicate.matches(0f)); + assertTrue(predicate.matches(0)); + } + + @Test + public void testBasePredicateGreaterThan() { + ActiveMQFilterPredicate predicate = new ActiveMQFilterPredicate<>(); + predicate.setOperation(GREATER_THAN.name()); + predicate.setValue("12"); + assertFalse(predicate.matches("foo")); + assertTrue(predicate.matches(42)); + assertFalse(predicate.matches(0L)); + assertFalse(predicate.matches(0f)); + assertFalse(predicate.matches(0)); + } +} diff --git a/docs/user-manual/management.adoc b/docs/user-manual/management.adoc index 7cc6c1cfa0..c08e51d44f 100644 --- a/docs/user-manual/management.adoc +++ b/docs/user-manual/management.adoc @@ -684,6 +684,7 @@ A handful of management operations support a special JSON syntax to filter resul ** `CONTAINS` ** `NOT_CONTAINS` ** `EQUALS` +** `NOT_EQUALS` ** `GREATER_THAN` ** `LESS_THAN` * `value`