NIFI-12483 Streamlined JMX Metrics Filtering Parameters

- Added bean name filter processing and added test cases

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #8134.
This commit is contained in:
exceptionfactory 2023-12-06 14:30:41 -06:00 committed by Pierre Villard
parent 17a331b9e1
commit 5c1b0a1140
No known key found for this signature in database
GPG Key ID: F92A93B30C07C6D5
2 changed files with 48 additions and 9 deletions

View File

@ -20,40 +20,68 @@ import org.apache.nifi.web.api.dto.JmxMetricsResultDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
public class JmxMetricsFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(JmxMetricsFilter.class);
private final static String MATCH_NOTHING = "~^";
private final static String MATCH_ALL = "";
private static final String MATCH_NOTHING = "~^";
private static final String NAME_SEPARATOR = "\\|";
private static final String REPLACE_CHARACTERS = "[\\^$.*()]";
private static final String EMPTY = "";
private final Pattern allowedNameFilter;
private final Pattern beanNameFilter;
private final Set<String> beanNameFilters;
public JmxMetricsFilter(final String allowedNameFilter, final String beanNameFilter) {
this.allowedNameFilter = createPattern(allowedNameFilter, MATCH_NOTHING);
this.beanNameFilter = createPattern(beanNameFilter, MATCH_ALL);
this.allowedNameFilter = createPattern(allowedNameFilter);
this.beanNameFilters = createBeanNameFilters(beanNameFilter);
}
private Pattern createPattern(final String filter, final String defaultValue) {
private Pattern createPattern(final String filter) {
try {
if (filter == null || filter.isEmpty()) {
return Pattern.compile(defaultValue);
return Pattern.compile(MATCH_NOTHING);
} else {
return Pattern.compile(filter);
}
} catch (PatternSyntaxException e) {
LOGGER.warn("Invalid JMX MBean filter pattern ignored [{}]", filter);
return Pattern.compile(defaultValue);
return Pattern.compile(MATCH_NOTHING);
}
}
private Set<String> createBeanNameFilters(final String filter) {
if (filter == null || filter.isEmpty()) {
return Collections.emptySet();
} else {
return Arrays.stream(
filter.split(NAME_SEPARATOR)).map(
name -> name.replaceAll(REPLACE_CHARACTERS, EMPTY)
)
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toSet());
}
}
public Collection<JmxMetricsResultDTO> filter(final Collection<JmxMetricsResultDTO> results) {
return results.stream()
.filter(result -> allowedNameFilter.asPredicate().test(result.getBeanName()))
.filter(result -> beanNameFilter.asPredicate().test(result.getBeanName()))
.filter(result -> {
final boolean included;
if (beanNameFilters.isEmpty()) {
included = true;
} else {
final String beanName = result.getBeanName();
included = beanNameFilters.stream().anyMatch(beanName::contains);
}
return included;
})
.collect(Collectors.toList());
}
}

View File

@ -35,6 +35,7 @@ class JmxMetricsFilterTest {
private static final String INVALID_REGEX = "(";
private static final String TEST_BEAN_NAME_ONE = "testBean1";
private static final String TEST_BEAN_NAME_TWO = "testBean2";
private static final String BEGIN_END_PATTERN = "^test.*$";
private static final JmxMetricsResultDTO RESULT_ONE = new JmxMetricsResultDTO(TEST_BEAN_NAME_ONE, null, null);
private static final JmxMetricsResultDTO RESULT_TWO = new JmxMetricsResultDTO(TEST_BEAN_NAME_TWO, null, null);
private static List<JmxMetricsResultDTO> results;
@ -56,6 +57,16 @@ class JmxMetricsFilterTest {
assertTrue(actual.containsAll(results));
}
@Test
public void testBeginEndPatternMatches() {
final JmxMetricsFilter metricsFilter = new JmxMetricsFilter(ALLOW_ALL_PATTERN, BEGIN_END_PATTERN);
final Collection<JmxMetricsResultDTO> actual = metricsFilter.filter(results);
assertEquals(actual.size(), 2);
assertTrue(actual.containsAll(results));
}
@Test
public void testAllowedNameFiltersRemovesMBeanFromResult() {
final JmxMetricsFilter metricsFilter = new JmxMetricsFilter(TEST_BEAN_NAME_ONE, EMPTY_STRING_PATTERN);