From f5918498c911fa6e8776828bfaff782d57cb0498 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 19 Feb 2020 19:12:18 -0800 Subject: [PATCH] Add CompositeAppender.compose(:Appender[]) and CompositeAppender.compose(:Iterable) methods to compose an array or Iterable of Appenders. Resolves gh-73. --- .../slf4j/logback/CompositeAppender.java | 50 +++++++++++++ .../logback/CompositeAppenderUnitTests.java | 75 +++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/spring-geode-starter-logging/src/main/java/org/springframework/geode/logging/slf4j/logback/CompositeAppender.java b/spring-geode-starter-logging/src/main/java/org/springframework/geode/logging/slf4j/logback/CompositeAppender.java index 33b41ea1..89823de9 100644 --- a/spring-geode-starter-logging/src/main/java/org/springframework/geode/logging/slf4j/logback/CompositeAppender.java +++ b/spring-geode-starter-logging/src/main/java/org/springframework/geode/logging/slf4j/logback/CompositeAppender.java @@ -15,6 +15,10 @@ */ package org.springframework.geode.logging.slf4j.logback; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import ch.qos.logback.core.Appender; import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.Context; @@ -54,6 +58,52 @@ public class CompositeAppender extends AppenderBase { return one == null ? two : two == null ? one : new CompositeAppender<>(one, two); } + /** + * Composes an array of {@link Appender Appenders} into a {@link CompositeAppender}. + * + * This operation is null-safe. + * + * @param {@link Class type} of the logging events processed by the {@link Appender Appenders}. + * @param appenders array of {@link Appender Appenders} to compose; may be {@literal null}. + * @return a composition of the array of {@link Appender Appenders}; returns {@literal null} if the array is empty. + * @see #compose(Iterable) + */ + @SuppressWarnings("unchecked") + public static Appender compose(Appender... appenders) { + + List> resolvedAppenders = appenders != null + ? Arrays.asList(appenders) + : Collections.emptyList(); + + return compose(resolvedAppenders); + + } + + /** + * Composes the {@link Iterable} of {@link Appender Appenders} into a {@link CompositeAppender}. + * + * This operation is null-safe. + * + * @param {@link Class type} of the logging events processed by the {@link Appender Appenders}. + * @param appenders {@link Iterable} of {@link Appender Appenders} to compose; may be {@literal null}. + * @return a composition of the {@link Iterable} of {@link Appender Appenders}; returns {@literal null} + * if the {@link Iterable} is {@literal null} or empty. + * @see #compose(Appender, Appender) + * @see java.lang.Iterable + */ + public static Appender compose(Iterable> appenders) { + + Appender currentAppender = null; + + appenders = appenders != null ? appenders : Collections::emptyIterator; + + for (Appender appender : appenders) { + currentAppender = compose(currentAppender, appender); + } + + return currentAppender; + } + /** * Constructs a new instance of {@link CompositeAppender} composed of {@link Appender} one and {@link Appender} two. * diff --git a/spring-geode-starter-logging/src/test/java/org/springframework/geode/logging/slf4j/logback/CompositeAppenderUnitTests.java b/spring-geode-starter-logging/src/test/java/org/springframework/geode/logging/slf4j/logback/CompositeAppenderUnitTests.java index 355e9f13..81615c2c 100644 --- a/spring-geode-starter-logging/src/test/java/org/springframework/geode/logging/slf4j/logback/CompositeAppenderUnitTests.java +++ b/spring-geode-starter-logging/src/test/java/org/springframework/geode/logging/slf4j/logback/CompositeAppenderUnitTests.java @@ -23,6 +23,9 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.util.Arrays; +import java.util.Collections; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -77,6 +80,78 @@ public class CompositeAppenderUnitTests { assertThat(composite.isStarted()).isTrue(); } + @Test + public void composeAppenderArray() { + + Appender mockAppenderOne = mock(Appender.class); + Appender mockAppenderTwo = mock(Appender.class); + Appender mockAppenderThree = mock(Appender.class); + + Appender composite = CompositeAppender.compose(mockAppenderOne, mockAppenderTwo, mockAppenderThree); + + assertThat(composite).isInstanceOf(CompositeAppender.class); + + Appender appenderOne = ((CompositeAppender) composite).getAppenderOne(); + Appender appenderTwo = ((CompositeAppender) composite).getAppenderTwo(); + + assertThat(appenderOne).isInstanceOf(CompositeAppender.class); + assertThat(appenderTwo).isEqualTo(mockAppenderThree); + assertThat(((CompositeAppender) appenderOne).getAppenderOne()).isEqualTo(mockAppenderOne); + assertThat(((CompositeAppender) appenderOne).getAppenderTwo()).isEqualTo(mockAppenderTwo); + } + + @Test + public void composeAppenderArrayWithOneAppender() { + assertThat(CompositeAppender.compose(this.mockAppenderOne)).isSameAs(this.mockAppenderOne); + } + + @Test + public void composeAppenderArrayWithZeroAppenders() { + assertThat(CompositeAppender.compose()).isNull(); + } + + @Test + public void composeAppenderArrayIsNullSafe() { + assertThat(CompositeAppender.compose((Appender[]) null)).isNull(); + } + + @Test + public void composeAppenderIterable() { + + Appender mockAppenderOne = mock(Appender.class); + Appender mockAppenderTwo = mock(Appender.class); + Appender mockAppenderThree = mock(Appender.class); + + Appender composite = + CompositeAppender.compose(Arrays.asList(mockAppenderOne, mockAppenderTwo, mockAppenderThree)); + + assertThat(composite).isInstanceOf(CompositeAppender.class); + + Appender appenderOne = ((CompositeAppender) composite).getAppenderOne(); + Appender appenderTwo = ((CompositeAppender) composite).getAppenderTwo(); + + assertThat(appenderOne).isInstanceOf(CompositeAppender.class); + assertThat(appenderTwo).isEqualTo(mockAppenderThree); + assertThat(((CompositeAppender) appenderOne).getAppenderOne()).isEqualTo(mockAppenderOne); + assertThat(((CompositeAppender) appenderOne).getAppenderTwo()).isEqualTo(mockAppenderTwo); + } + + @Test + public void composeAppenderIterableWithOneAppender() { + assertThat(CompositeAppender.compose(Collections.singletonList(this.mockAppenderTwo))) + .isSameAs(this.mockAppenderTwo); + } + + @Test + public void composeAppenderIterableWithZeroAppenders() { + assertThat(CompositeAppender.compose(Collections.emptyList())).isNull(); + } + + @Test + public void composeAppenderIterableIsNullSafe() { + assertThat(CompositeAppender.compose((Iterable>) null)).isNull(); + } + @Test public void setContextConfiguresContextOnCompositeAppenderAndComposedAppenders() {