diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/CapturingLogger.java b/nifi-mock/src/main/java/org/apache/nifi/util/CapturingLogger.java new file mode 100644 index 0000000000..f4045291b3 --- /dev/null +++ b/nifi-mock/src/main/java/org/apache/nifi/util/CapturingLogger.java @@ -0,0 +1,413 @@ +package org.apache.nifi.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * Implementation of SLF4J logger that records every log message and provides a mechanism + * to retrieve them. + * + */ +public class CapturingLogger implements Logger { + + private final Logger logger; + + private List traceMessages = new ArrayList<>(); + private List debugMessages = new ArrayList<>(); + private List infoMessages = new ArrayList<>(); + private List warnMessages = new ArrayList<>(); + private List errorMessages = new ArrayList<>(); + + public CapturingLogger(final Logger logger) { + this.logger = logger; + } + public List getTraceMessages() { + return Collections.unmodifiableList(traceMessages); + } + public List getDebugMessages() { + return Collections.unmodifiableList(debugMessages); + } + public List getInfoMessages() { + return Collections.unmodifiableList(infoMessages); + } + public List getWarnMessages() { + return Collections.unmodifiableList(warnMessages); + } + public List getErrorMessages() { + return Collections.unmodifiableList(errorMessages); + } + + @Override + public String getName() { + return logger.getName(); + } + + @Override + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + public void trace(String msg) { + traceMessages.add(new LogMessage(null, msg, null)); + logger.trace(msg); + } + + @Override + public void trace(String format, Object arg) { + traceMessages.add(new LogMessage(null, format, null, arg)); + logger.trace(format, arg); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + traceMessages.add(new LogMessage(null, format, null, arg1, arg2)); + logger.trace(format, arg1, arg2); + } + + @Override + public void trace(String format, Object... arguments) { + traceMessages.add(new LogMessage(null, format, null, arguments)); + logger.trace(format, arguments); + } + + @Override + public void trace(String msg, Throwable t) { + traceMessages.add(new LogMessage(null, msg, t)); + logger.trace(msg, t); + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return logger.isTraceEnabled(marker); + } + + @Override + public void trace(Marker marker, String msg) { + traceMessages.add(new LogMessage(marker, msg, null)); + logger.trace(marker, msg); + + } + + @Override + public void trace(Marker marker, String format, Object arg) { + traceMessages.add(new LogMessage(marker, format, null, arg)); + logger.trace(marker, format, arg); + + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + traceMessages.add(new LogMessage(marker, format, null, arg1, arg2)); + logger.trace(marker, format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + traceMessages.add(new LogMessage(marker, format, null, argArray)); + logger.trace(marker, format, argArray); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + traceMessages.add(new LogMessage(marker, msg, t)); + logger.trace(marker, msg, t); + } + + // DEBUG + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public void debug(String msg) { + debugMessages.add(new LogMessage(null, msg, null)); + logger.debug(msg); + } + + @Override + public void debug(String format, Object arg) { + debugMessages.add(new LogMessage(null, format, null, arg)); + logger.debug(format, arg); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + debugMessages.add(new LogMessage(null, format, null, arg1, arg2)); + logger.debug(format, arg1, arg2); + } + + @Override + public void debug(String format, Object... arguments) { + debugMessages.add(new LogMessage(null, format, null, arguments)); + logger.debug(format, arguments); + } + + @Override + public void debug(String msg, Throwable t) { + debugMessages.add(new LogMessage(null, msg, t)); + logger.debug(msg, t); + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return logger.isDebugEnabled(marker); + } + + @Override + public void debug(Marker marker, String msg) { + debugMessages.add(new LogMessage(marker, msg, null)); + logger.debug(marker, msg); + + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debugMessages.add(new LogMessage(marker, format, null, arg)); + logger.debug(marker, format, arg); + + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debugMessages.add(new LogMessage(marker, format, null, arg1, arg2)); + logger.debug(marker, format, arg1, arg2); + } + + @Override + public void debug(Marker marker, String format, Object... argArray) { + debugMessages.add(new LogMessage(marker, format, null, argArray)); + logger.debug(marker, format, argArray); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debugMessages.add(new LogMessage(marker, msg, t)); + logger.debug(marker, msg, t); + } + + + + // INFO + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public void info(String msg) { + infoMessages.add(new LogMessage(null, msg, null)); + logger.info(msg); + } + + @Override + public void info(String format, Object arg) { + infoMessages.add(new LogMessage(null, format, null, arg)); + logger.info(format, arg); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + infoMessages.add(new LogMessage(null, format, null, arg1, arg2)); + logger.info(format, arg1, arg2); + } + + @Override + public void info(String format, Object... arguments) { + infoMessages.add(new LogMessage(null, format, null, arguments)); + logger.info(format, arguments); + } + + @Override + public void info(String msg, Throwable t) { + infoMessages.add(new LogMessage(null, msg, t)); + logger.info(msg, t); + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return logger.isInfoEnabled(marker); + } + + @Override + public void info(Marker marker, String msg) { + infoMessages.add(new LogMessage(marker, msg, null)); + logger.info(marker, msg); + + } + + @Override + public void info(Marker marker, String format, Object arg) { + infoMessages.add(new LogMessage(marker, format, null, arg)); + logger.info(marker, format, arg); + + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + infoMessages.add(new LogMessage(marker, format, null, arg1, arg2)); + logger.info(marker, format, arg1, arg2); + } + + @Override + public void info(Marker marker, String format, Object... argArray) { + infoMessages.add(new LogMessage(marker, format, null, argArray)); + logger.info(marker, format, argArray); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + infoMessages.add(new LogMessage(marker, msg, t)); + logger.debug(marker, msg, t); + } + // WARN + @Override + public boolean isWarnEnabled() { + return logger.isWarnEnabled(); + } + + @Override + public void warn(String msg) { + warnMessages.add(new LogMessage(null, msg, null)); + logger.warn(msg); + } + + @Override + public void warn(String format, Object arg) { + warnMessages.add(new LogMessage(null, format, null, arg)); + logger.warn(format, arg); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + warnMessages.add(new LogMessage(null, format, null, arg1, arg2)); + logger.warn(format, arg1, arg2); + } + + @Override + public void warn(String format, Object... arguments) { + warnMessages.add(new LogMessage(null, format, null, arguments)); + logger.warn(format, arguments); + } + + @Override + public void warn(String msg, Throwable t) { + warnMessages.add(new LogMessage(null, msg, t)); + logger.warn(msg, t); + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return logger.isWarnEnabled(marker); + } + + @Override + public void warn(Marker marker, String msg) { + warnMessages.add(new LogMessage(marker, msg, null)); + logger.warn(marker, msg); + + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warnMessages.add(new LogMessage(marker, format, null, arg)); + logger.warn(marker, format, arg); + + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warnMessages.add(new LogMessage(marker, format, null, arg1, arg2)); + logger.warn(marker, format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String format, Object... argArray) { + warnMessages.add(new LogMessage(marker, format, null, argArray)); + logger.warn(marker, format, argArray); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + warnMessages.add(new LogMessage(marker, msg, t)); + logger.warn(marker, msg, t); + } + // ERROR + @Override + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } + + @Override + public void error(String msg) { + errorMessages.add(new LogMessage(null, msg, null)); + logger.error(msg); + } + + @Override + public void error(String format, Object arg) { + errorMessages.add(new LogMessage(null, format, null, arg)); + logger.error(format, arg); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + errorMessages.add(new LogMessage(null, format, null, arg1, arg2)); + logger.error(format, arg1, arg2); + } + + @Override + public void error(String format, Object... arguments) { + errorMessages.add(new LogMessage(null, format, null, arguments)); + logger.error(format, arguments); + } + + @Override + public void error(String msg, Throwable t) { + errorMessages.add(new LogMessage(null, msg, t)); + logger.error(msg, t); + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return logger.isErrorEnabled(marker); + } + + @Override + public void error(Marker marker, String msg) { + errorMessages.add(new LogMessage(marker, msg, null)); + logger.error(marker, msg); + + } + + @Override + public void error(Marker marker, String format, Object arg) { + errorMessages.add(new LogMessage(marker, format, null, arg)); + logger.error(marker, format, arg); + + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + errorMessages.add(new LogMessage(marker, format, null, arg1, arg2)); + logger.error(marker, format, arg1, arg2); + } + + @Override + public void error(Marker marker, String format, Object... argArray) { + errorMessages.add(new LogMessage(marker, format, null, argArray)); + logger.error(marker, format, argArray); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + errorMessages.add(new LogMessage(marker, msg, t)); + logger.error(marker, msg, t); + } + +} diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/LogMessage.java b/nifi-mock/src/main/java/org/apache/nifi/util/LogMessage.java new file mode 100644 index 0000000000..e12b69502e --- /dev/null +++ b/nifi-mock/src/main/java/org/apache/nifi/util/LogMessage.java @@ -0,0 +1,29 @@ +package org.apache.nifi.util; + +import org.slf4j.Marker; + +public class LogMessage { + private final Marker marker; + private final String msg; + private final Throwable throwable; + private final Object[] args; + public LogMessage(final Marker marker, final String msg, final Throwable t, final Object... args) { + this.marker = marker; + this.msg = msg; + this.throwable = t; + this.args = args; + } + + public Marker getMarker() { + return marker; + } + public String getMsg() { + return msg; + } + public Throwable getThrowable() { + return throwable; + } + public Object[] getArgs() { + return args; + } +} \ No newline at end of file diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorInitializationContext.java b/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorInitializationContext.java index 2e5d3eb25e..6e94943004 100644 --- a/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorInitializationContext.java +++ b/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorInitializationContext.java @@ -21,13 +21,12 @@ import java.util.UUID; import org.apache.nifi.controller.ControllerService; import org.apache.nifi.controller.ControllerServiceLookup; -import org.apache.nifi.logging.ProcessorLog; import org.apache.nifi.processor.Processor; import org.apache.nifi.processor.ProcessorInitializationContext; public class MockProcessorInitializationContext implements ProcessorInitializationContext, ControllerServiceLookup { - private final ProcessorLog logger; + private final MockProcessorLog logger; private final String processorId; private final MockProcessContext context; @@ -43,7 +42,7 @@ public class MockProcessorInitializationContext implements ProcessorInitializati } @Override - public ProcessorLog getLogger() { + public MockProcessorLog getLogger() { return logger; } diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorLog.java b/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorLog.java index 837784b042..0bc587f11d 100644 --- a/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorLog.java +++ b/nifi-mock/src/main/java/org/apache/nifi/util/MockProcessorLog.java @@ -16,19 +16,56 @@ */ package org.apache.nifi.util; +import java.util.List; + import org.apache.nifi.logging.ProcessorLog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MockProcessorLog implements ProcessorLog { - private final Logger logger; + private final CapturingLogger logger; private final Object component; public MockProcessorLog(final String componentId, final Object component) { - this.logger = LoggerFactory.getLogger(component.getClass()); + this.logger = new CapturingLogger(LoggerFactory.getLogger(component.getClass())); this.component = component; } + + /** + * @return a {@link List} of all TRACE level messages recorded by this {@link Logger}. + */ + public List getTraceMessages() { + return logger.getTraceMessages(); + } + + /** + * @return a {@link List} of all DEBUG level messages recorded by this {@link Logger}. + */ + public List getDebugMessages() { + return logger.getDebugMessages(); + } + + /** + * @return a {@link List} of all INFO level messages recorded by this {@link Logger}. + */ + public List getInfoMessages() { + return logger.getInfoMessages(); + } + + /** + * @return a {@link List} of all WARN level messages recorded by this {@link Logger}. + */ + public List getWarnMessages() { + return logger.getWarnMessages(); + } + + /** + * @return a {@link List} of all ERROR level messages recorded by this {@link Logger}. + */ + public List getErrorMessages() { + return logger.getErrorMessages(); + } private Object[] addProcessor(final Object[] originalArgs) { return prependToArgs(originalArgs, component); diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/StandardProcessorTestRunner.java b/nifi-mock/src/main/java/org/apache/nifi/util/StandardProcessorTestRunner.java index 925f0d8f2c..9cb514a090 100644 --- a/nifi-mock/src/main/java/org/apache/nifi/util/StandardProcessorTestRunner.java +++ b/nifi-mock/src/main/java/org/apache/nifi/util/StandardProcessorTestRunner.java @@ -86,6 +86,8 @@ public class StandardProcessorTestRunner implements TestRunner { private static final Set> deprecatedTypeAnnotations = new HashSet<>(); private static final Set> deprecatedMethodAnnotations = new HashSet<>(); + private final Map controllerServiceLoggers = new HashMap<>(); + private final MockProcessorLog logger; static { // do this in a separate method, just so that we can add a @SuppressWarnings annotation @@ -106,6 +108,7 @@ public class StandardProcessorTestRunner implements TestRunner { final MockProcessorInitializationContext mockInitContext = new MockProcessorInitializationContext(processor, context); processor.initialize(mockInitContext); + logger = mockInitContext.getLogger(); try { ReflectionUtils.invokeMethodsWithAnnotation(OnAdded.class, processor); @@ -574,7 +577,8 @@ public class StandardProcessorTestRunner implements TestRunner { // } // } - final ComponentLog logger = new MockProcessorLog(identifier, service); + final MockProcessorLog logger = new MockProcessorLog(identifier, service); + controllerServiceLoggers.put(identifier, logger); final MockControllerServiceInitializationContext initContext = new MockControllerServiceInitializationContext(requireNonNull(service), requireNonNull(identifier), logger); initContext.addControllerServices(context); service.initialize(initContext); @@ -767,5 +771,13 @@ public class StandardProcessorTestRunner implements TestRunner { public void clearProvenanceEvents() { sharedState.clearProvenanceEvents(); } + + public MockProcessorLog getLogger() { + return logger; + } + public MockProcessorLog getControllerServiceLogger(final String identifier) { + return controllerServiceLoggers.get(identifier); + } + } diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/TestRunner.java b/nifi-mock/src/main/java/org/apache/nifi/util/TestRunner.java index 6c8f192b35..0bb588c2d4 100644 --- a/nifi-mock/src/main/java/org/apache/nifi/util/TestRunner.java +++ b/nifi-mock/src/main/java/org/apache/nifi/util/TestRunner.java @@ -824,4 +824,18 @@ public interface TestRunner { * Clears the Provenance Events that have been emitted by the Processor */ void clearProvenanceEvents(); + + /** + * Returns the {@link MockProcessorLog} that is used by the Processor under test. + * @return the logger + */ + public MockProcessorLog getLogger(); + + /** + * Returns the {@link MockProcessorLog} that is used by the specified controller service. + * + * @param identifier a controller service identifier + * @return the logger + */ + public MockProcessorLog getControllerServiceLogger(final String identifier); }