/* * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.amqp.rabbit.log4j2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import java.io.IOException; import java.net.URI; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageDeliveryMode; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.junit.BrokerRunning; import org.springframework.amqp.utils.test.TestUtils; import org.springframework.core.io.ClassPathResource; import org.springframework.test.util.ReflectionTestUtils; /** * @author Gary Russell * @author Stephen Oakey * @author Artem Bilan * * @since 1.6 */ public class AmqpAppenderTests { @ClassRule public static BrokerRunning brokerRunning = BrokerRunning.isRunning(); private static final LoggerContext LOGGER_CONTEXT = (LoggerContext) LogManager.getContext(false); private static final URI ORIGINAL_LOGGER_CONFIG = LOGGER_CONTEXT.getConfigLocation(); @BeforeClass public static void setup() throws IOException { LOGGER_CONTEXT.setConfigLocation(new ClassPathResource("log4j2-amqp-appender.xml").getURI()); LOGGER_CONTEXT.reconfigure(); } @AfterClass public static void teardown() { LOGGER_CONTEXT.setConfigLocation(ORIGINAL_LOGGER_CONFIG); LOGGER_CONTEXT.reconfigure(); brokerRunning.deleteQueues("log4jTest", "log4j2Test"); brokerRunning.deleteExchanges("log4j2Test"); } @Test public void test() { CachingConnectionFactory ccf = new CachingConnectionFactory("localhost"); RabbitTemplate template = new RabbitTemplate(ccf); RabbitAdmin admin = new RabbitAdmin(ccf); FanoutExchange fanout = new FanoutExchange("log4j2Test"); admin.declareExchange(fanout); Queue queue = new Queue("log4j2Test"); admin.declareQueue(queue); admin.declareBinding(BindingBuilder.bind(queue).to(fanout)); Logger logger = LogManager.getLogger("foo"); logger.info("foo"); template.setReceiveTimeout(10000); Message received = template.receive(queue.getName()); assertNotNull(received); assertEquals("testAppId.foo.INFO", received.getMessageProperties().getReceivedRoutingKey()); } @Test public void testProperties() { Logger logger = LogManager.getLogger("foo"); AmqpAppender appender = (AmqpAppender) TestUtils.getPropertyValue(logger, "context.configuration.appenders", Map.class).get("rabbitmq"); Object manager = TestUtils.getPropertyValue(appender, "manager"); // <RabbitMQ name="rabbitmq" // addresses="localhost:5672" // host="localhost" port="5672" user="guest" password="guest" virtualHost="/" // exchange="log4j2Test" exchangeType="fanout" declareExchange="true" // durable="true" autoDelete="false" // applicationId="testAppId" routingKeyPattern="%X{applicationId}.%c.%p" // contentType="text/plain" contentEncoding="UTF-8" generateId="true" // deliveryMode="NON_PERSISTENT" // charset="UTF-8" // senderPoolSize="3" maxSenderRetries="5"> // </RabbitMQ> assertEquals("localhost:5672", TestUtils.getPropertyValue(manager, "addresses")); assertEquals("localhost", TestUtils.getPropertyValue(manager, "host")); assertEquals(5672, TestUtils.getPropertyValue(manager, "port")); assertEquals("guest", TestUtils.getPropertyValue(manager, "username")); assertEquals("guest", TestUtils.getPropertyValue(manager, "password")); assertEquals("/", TestUtils.getPropertyValue(manager, "virtualHost")); assertEquals("log4j2Test", TestUtils.getPropertyValue(manager, "exchangeName")); assertEquals("fanout", TestUtils.getPropertyValue(manager, "exchangeType")); assertTrue(TestUtils.getPropertyValue(manager, "declareExchange", Boolean.class)); assertTrue(TestUtils.getPropertyValue(manager, "durable", Boolean.class)); assertFalse(TestUtils.getPropertyValue(manager, "autoDelete", Boolean.class)); assertEquals("testAppId", TestUtils.getPropertyValue(manager, "applicationId")); assertEquals("%X{applicationId}.%c.%p", TestUtils.getPropertyValue(manager, "routingKeyPattern")); assertEquals("text/plain", TestUtils.getPropertyValue(manager, "contentType")); assertEquals("UTF-8", TestUtils.getPropertyValue(manager, "contentEncoding")); assertTrue(TestUtils.getPropertyValue(manager, "generateId", Boolean.class)); assertEquals(MessageDeliveryMode.NON_PERSISTENT, TestUtils.getPropertyValue(manager, "deliveryMode")); assertEquals("UTF-8", TestUtils.getPropertyValue(manager, "contentEncoding")); assertEquals(3, TestUtils.getPropertyValue(manager, "senderPoolSize")); assertEquals(5, TestUtils.getPropertyValue(manager, "maxSenderRetries")); } @Test public void testDefaultConfiguration() { @SuppressWarnings("resource") AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean, never()).setUseSSL(anyBoolean()); } @Test public void testCustomHostInformation() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); String host = "rabbitmq.com"; int port = 5671; String username = "user"; String password = "password"; String virtualHost = "vhost"; ReflectionTestUtils.setField(manager, "host", host); ReflectionTestUtils.setField(manager, "port", port); ReflectionTestUtils.setField(manager, "username", username); ReflectionTestUtils.setField(manager, "password", password); ReflectionTestUtils.setField(manager, "virtualHost", virtualHost); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verify(bean).setHost(host); verify(bean).setPort(port); verify(bean).setUsername(username); verify(bean).setPassword(password); verify(bean).setVirtualHost(virtualHost); } @Test public void testDefaultSslConfiguration() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); ReflectionTestUtils.setField(manager, "useSsl", true); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean).setUseSSL(eq(true)); verify(bean, never()).setSslAlgorithm(anyString()); } @Test public void testSslConfigurationWithAlgorithm() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); ReflectionTestUtils.setField(manager, "useSsl", true); String sslAlgorithm = "TLSv2"; ReflectionTestUtils.setField(manager, "sslAlgorithm", sslAlgorithm); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean).setUseSSL(eq(true)); verify(bean).setSslAlgorithm(eq(sslAlgorithm)); } @Test public void testSslConfigurationWithSslPropertiesResource() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); ReflectionTestUtils.setField(manager, "useSsl", true); String path = "ssl.properties"; ReflectionTestUtils.setField(manager, "sslPropertiesLocation", "classpath:" + path); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean).setUseSSL(eq(true)); verify(bean).setSslPropertiesLocation(eq(new ClassPathResource(path))); verify(bean, never()).setKeyStore(anyString()); verify(bean, never()).setKeyStorePassphrase(anyString()); verify(bean, never()).setKeyStoreType(anyString()); verify(bean, never()).setTrustStore(anyString()); verify(bean, never()).setTrustStorePassphrase(anyString()); verify(bean, never()).setTrustStoreType(anyString()); } @Test public void testSslConfigurationWithKeyAndTrustStore() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); ReflectionTestUtils.setField(manager, "useSsl", true); String keyStore = "file:/path/to/client/keycert.p12"; String keyStorePassphrase = "secret"; String keyStoreType = "foo"; String trustStore = "file:/path/to/client/truststore"; String trustStorePassphrase = "secret2"; String trustStoreType = "bar"; ReflectionTestUtils.setField(manager, "keyStore", keyStore); ReflectionTestUtils.setField(manager, "keyStorePassphrase", keyStorePassphrase); ReflectionTestUtils.setField(manager, "keyStoreType", keyStoreType); ReflectionTestUtils.setField(manager, "trustStore", trustStore); ReflectionTestUtils.setField(manager, "trustStorePassphrase", trustStorePassphrase); ReflectionTestUtils.setField(manager, "trustStoreType", trustStoreType); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean).setUseSSL(eq(true)); verify(bean, never()).setSslPropertiesLocation(any()); verify(bean).setKeyStore(keyStore); verify(bean).setKeyStorePassphrase(keyStorePassphrase); verify(bean).setKeyStoreType(keyStoreType); verify(bean).setTrustStore(trustStore); verify(bean).setTrustStorePassphrase(trustStorePassphrase); verify(bean).setTrustStoreType(trustStoreType); } @Test public void testSslConfigurationWithKeyAndTrustStoreDefaultTypes() { AmqpAppender.AmqpManager manager = new AmqpAppender.AmqpManager(LOGGER_CONTEXT, "test"); ReflectionTestUtils.setField(manager, "useSsl", true); RabbitConnectionFactoryBean bean = mock(RabbitConnectionFactoryBean.class); manager.configureRabbitConnectionFactory(bean); verifyDefaultHostProperties(bean); verify(bean).setUseSSL(eq(true)); verify(bean).setKeyStoreType("JKS"); verify(bean).setTrustStoreType("JKS"); } private void verifyDefaultHostProperties(RabbitConnectionFactoryBean bean) { verify(bean).setHost("localhost"); verify(bean).setPort(5672); verify(bean).setUsername("guest"); verify(bean).setPassword("guest"); verify(bean).setVirtualHost("/"); } }