|
16 | 16 | */ |
17 | 17 | package org.apache.logging.log4j.core.filter; |
18 | 18 |
|
19 | | -import com.fasterxml.jackson.databind.DeserializationFeature; |
20 | | -import com.fasterxml.jackson.databind.ObjectMapper; |
| 19 | +import static java.nio.charset.StandardCharsets.UTF_8; |
| 20 | + |
21 | 21 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; |
22 | 22 | import java.io.File; |
23 | 23 | import java.io.FileInputStream; |
|
38 | 38 | import org.apache.logging.log4j.core.config.ConfigurationException; |
39 | 39 | import org.apache.logging.log4j.core.config.ConfigurationScheduler; |
40 | 40 | import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; |
41 | | -import org.apache.logging.log4j.core.filter.mutable.KeyValuePairConfig; |
42 | 41 | import org.apache.logging.log4j.core.net.ssl.SslConfiguration; |
43 | 42 | import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory; |
44 | 43 | import org.apache.logging.log4j.core.util.AuthorizationProvider; |
|
52 | 51 | import org.apache.logging.log4j.plugins.PluginAliases; |
53 | 52 | import org.apache.logging.log4j.plugins.PluginAttribute; |
54 | 53 | import org.apache.logging.log4j.plugins.PluginFactory; |
| 54 | +import org.apache.logging.log4j.util.JsonReader; |
55 | 55 | import org.apache.logging.log4j.util.PerformanceSensitive; |
56 | 56 | import org.apache.logging.log4j.util.PropertyEnvironment; |
57 | 57 |
|
|
64 | 64 | @PerformanceSensitive("allocation") |
65 | 65 | public class MutableThreadContextMapFilter extends AbstractFilter { |
66 | 66 |
|
67 | | - private static final ObjectMapper MAPPER = |
68 | | - new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
69 | 67 | private static final KeyValuePair[] EMPTY_ARRAY = {}; |
70 | 68 |
|
71 | 69 | private volatile Filter filter; |
@@ -456,44 +454,64 @@ private static ConfigResult getConfig( |
456 | 454 | final ConfigResult configResult = new ConfigResult(); |
457 | 455 | if (result.getStatus() == Status.SUCCESS) { |
458 | 456 | LOGGER.debug("Processing Debug key/value pairs from: {}", source.toString()); |
459 | | - try { |
460 | | - final KeyValuePairConfig keyValuePairConfig = MAPPER.readValue(inputStream, KeyValuePairConfig.class); |
461 | | - if (keyValuePairConfig != null) { |
462 | | - final Map<String, String[]> configs = keyValuePairConfig.getConfigs(); |
463 | | - if (configs != null && configs.size() > 0) { |
464 | | - final List<KeyValuePair> pairs = new ArrayList<>(); |
465 | | - for (Map.Entry<String, String[]> entry : configs.entrySet()) { |
466 | | - final String key = entry.getKey(); |
467 | | - for (final String value : entry.getValue()) { |
468 | | - if (value != null) { |
469 | | - pairs.add(new KeyValuePair(key, value)); |
| 457 | + parseJsonConfiguration(inputStream, configResult); |
| 458 | + } else { |
| 459 | + configResult.status = result.getStatus(); |
| 460 | + } |
| 461 | + return configResult; |
| 462 | + } |
| 463 | + |
| 464 | + /** |
| 465 | + * Parses a JSON configuration file. |
| 466 | + * <pre> |
| 467 | + * { |
| 468 | + * "config": { |
| 469 | + * "loginId": ["rgoers", "adam"], |
| 470 | + * "accountNumber": ["30510263"] |
| 471 | + * } |
| 472 | + * } |
| 473 | + * </pre> |
| 474 | + */ |
| 475 | + private static void parseJsonConfiguration(final InputStream inputStream, final ConfigResult configResult) { |
| 476 | + try { |
| 477 | + final Object wrapper = JsonReader.read(new String(inputStream.readAllBytes(), UTF_8)); |
| 478 | + if (wrapper instanceof Map wrapperMap) { |
| 479 | + final Object config = wrapperMap.get("configs"); |
| 480 | + if (config instanceof Map<?, ?> configMap && configMap.size() > 0) { |
| 481 | + final List<KeyValuePair> pairs = new ArrayList<>(); |
| 482 | + for (Map.Entry<?, ?> entry : configMap.entrySet()) { |
| 483 | + final String key = String.valueOf(entry.getKey()); |
| 484 | + final Object jsonArray = entry.getValue(); |
| 485 | + if (jsonArray instanceof List<?> valueList) { |
| 486 | + for (final Object value : valueList) { |
| 487 | + if (value instanceof String stringValue) { |
| 488 | + pairs.add(new KeyValuePair(key, stringValue)); |
470 | 489 | } else { |
471 | | - LOGGER.warn("Ignoring null value for {}", key); |
| 490 | + LOGGER.warn("Ignoring null value for {}: {}", key, value); |
472 | 491 | } |
473 | 492 | } |
474 | | - } |
475 | | - if (pairs.size() > 0) { |
476 | | - configResult.pairs = pairs.toArray(EMPTY_ARRAY); |
477 | | - configResult.status = Status.SUCCESS; |
478 | 493 | } else { |
479 | | - configResult.status = Status.EMPTY; |
| 494 | + LOGGER.warn("Ignoring the value for {}, which is not an array: {}", key, jsonArray); |
480 | 495 | } |
| 496 | + } |
| 497 | + if (pairs.size() > 0) { |
| 498 | + configResult.pairs = pairs.toArray(EMPTY_ARRAY); |
| 499 | + configResult.status = Status.SUCCESS; |
481 | 500 | } else { |
482 | | - LOGGER.debug("No configuration data in {}", source.toString()); |
483 | 501 | configResult.status = Status.EMPTY; |
484 | 502 | } |
485 | 503 | } else { |
486 | | - LOGGER.warn("No configs element in MutableThreadContextMapFilter configuration"); |
487 | | - configResult.status = Status.ERROR; |
| 504 | + LOGGER.debug("No configuration data in {}", wrapper); |
| 505 | + configResult.status = Status.EMPTY; |
488 | 506 | } |
489 | | - } catch (Exception ex) { |
490 | | - LOGGER.warn("Invalid key/value pair configuration, input ignored: {}", ex.getMessage()); |
| 507 | + } else { |
| 508 | + LOGGER.warn("No configs element in MutableThreadContextMapFilter configuration"); |
491 | 509 | configResult.status = Status.ERROR; |
492 | 510 | } |
493 | | - } else { |
494 | | - configResult.status = result.getStatus(); |
| 511 | + } catch (Exception ex) { |
| 512 | + LOGGER.warn("Invalid key/value pair configuration, input ignored: {}", ex.getMessage()); |
| 513 | + configResult.status = Status.ERROR; |
495 | 514 | } |
496 | | - return configResult; |
497 | 515 | } |
498 | 516 |
|
499 | 517 | private static class NoOpFilter extends AbstractFilter { |
|
0 commit comments