fix bug in /status/properties filtering (#13045)

* fix bug in /status/properties filtering

* Refactor tests to use jackson for parsing druid.server.hiddenProperties instead of hacky string modifications

* make javadoc more descriptive using example

* add in a sanity assertion that raw properties keyset size is greater than filtered properties keyset size
This commit is contained in:
Lucas Capistrant 2022-09-07 19:45:28 -05:00 committed by GitHub
parent 7e20d70242
commit 99fd22c79b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 15 deletions

View File

@ -43,6 +43,7 @@ import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -84,6 +85,9 @@ public class StatusResource
/**
* filter out entries from allProperties with key containing elements in hiddenProperties (case insensitive)
*
* for example, if hiddenProperties = ["pwd"] and allProperties = {"foopwd": "secret", "foo": "bar", "my.pwd": "secret"},
* this method will return {"foo":"bar"}
*
* @return map of properties that are not filtered out.
*/
@Nonnull
@ -92,15 +96,15 @@ public class StatusResource
Map<String, String> allProperties
)
{
return Maps.filterEntries(
allProperties,
(entry) -> hiddenProperties
.stream()
.anyMatch(
hiddenPropertyElement ->
!StringUtils.toLowerCase(entry.getKey()).contains(StringUtils.toLowerCase(hiddenPropertyElement))
)
Map<String, String> propertyCopy = new HashMap<>(allProperties);
allProperties.keySet().forEach(
(key) -> {
if (hiddenProperties.stream().anyMatch((hiddenProperty) -> StringUtils.toLowerCase(key).contains(StringUtils.toLowerCase(hiddenProperty)))) {
propertyCopy.remove(key);
}
}
);
return propertyCopy;
}
@GET

View File

@ -19,7 +19,8 @@
package org.apache.druid.server;
import com.google.common.base.Splitter;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -32,9 +33,9 @@ import org.junit.Test;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
@ -64,18 +65,18 @@ public class StatusResourceTest
}
@Test
public void testHiddenProperties()
public void testHiddenProperties() throws Exception
{
testHiddenPropertiesWithPropertyFileName("status.resource.test.runtime.properties");
}
@Test
public void testHiddenPropertiesContain()
public void testHiddenPropertiesContain() throws Exception
{
testHiddenPropertiesWithPropertyFileName("status.resource.test.runtime.hpc.properties");
}
private void testHiddenPropertiesWithPropertyFileName(String fileName)
private void testHiddenPropertiesWithPropertyFileName(String fileName) throws Exception
{
Injector injector = Guice.createInjector(Collections.singletonList(new PropertiesModule(Collections.singletonList(
fileName))));
@ -84,8 +85,16 @@ public class StatusResourceTest
.stream()
.map(StringUtils::toLowerCase)
.collect(Collectors.toSet());
Set<String> hiddenProperties = new HashSet<>();
Splitter.on(",").split(returnedProperties.get("druid.server.hiddenProperties")).forEach(hiddenProperties::add);
Assert.assertTrue(
"The list of unfiltered Properties is not > the list of filtered Properties?!?",
injector.getInstance(Properties.class).stringPropertyNames().size() > returnedProperties.size()
);
Set<String> hiddenProperties = new ObjectMapper().readValue(
returnedProperties.get("druid.server.hiddenProperties"),
new TypeReference<Set<String>>() {});
hiddenProperties.forEach(
(property) -> {
lowerCasePropertyNames.forEach(