This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch jee-deletion in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit e048823825e859d4b46787976b9c6b7abc7e764b Author: Volkan Yazıcı <[email protected]> AuthorDate: Mon Nov 20 12:10:02 2023 +0100 Delete SMTP appender (#1966) --- .../log4j/jul/test/Log4jBridgeHandlerTest.java | 1 - .../src/test/resources/logging-test.properties | 2 - log4j-parent/pom.xml | 13 - log4j-smtp/pom.xml | 119 ------ .../logging/log4j/smtp/MimeMessageBuilder.java | 93 ----- .../logging/log4j/smtp/appender/SmtpAppender.java | 276 -------------- .../logging/log4j/smtp/appender/SmtpManager.java | 398 --------------------- .../logging/log4j/smtp/appender/package-info.java | 22 -- .../apache/logging/log4j/smtp/package-info.java | 22 -- .../logging/dumbster/smtp/SimpleSmtpServer.java | 279 --------------- .../logging/dumbster/smtp/SmtpActionType.java | 202 ----------- .../apache/logging/dumbster/smtp/SmtpMessage.java | 154 -------- .../apache/logging/dumbster/smtp/SmtpRequest.java | 231 ------------ .../apache/logging/dumbster/smtp/SmtpResponse.java | 75 ---- .../apache/logging/dumbster/smtp/SmtpState.java | 121 ------- .../org/apache/logging/dumbster/smtp/readme.txt | 4 - .../log4j/smtp/appender/SmtpAppenderAsyncTest.java | 98 ----- .../log4j/smtp/appender/SmtpAppenderTest.java | 180 ---------- .../log4j/smtp/appender/SmtpManagerTest.java | 86 ----- .../src/test/resources/SmtpAppenderAsyncTest.xml | 42 --- pom.xml | 7 - src/site/asciidoc/runtime-dependencies.adoc | 3 - 22 files changed, 2428 deletions(-) diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java index 652362ffc9..6ecad4ee37 100644 --- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java +++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/test/Log4jBridgeHandlerTest.java @@ -290,7 +290,6 @@ public class Log4jBridgeHandlerTest { assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested.deeplyNested", java.util.logging.Level.INFO); // these are set in logging.properties but not in log4j2.xml: assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested", null); - assertLogLevel("javax.mail", null); // these should not exist: assertLogLevel("log4j.Log4jBridgeHandlerTest", null); assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested", null); diff --git a/log4j-jul/src/test/resources/logging-test.properties b/log4j-jul/src/test/resources/logging-test.properties index 9a0a4756c7..169e8b2aa4 100644 --- a/log4j-jul/src/test/resources/logging-test.properties +++ b/log4j-jul/src/test/resources/logging-test.properties @@ -38,8 +38,6 @@ java.util.logging.SimpleFormatter.format = JUL: %1$tT.%1$tL %4$s [%3$s: %2$s] # out-comment to use default of "INFO" - will be set by level propagation to DEBUG=FINE again #.level = FINE org.apache.logging.log4j.jul.Log4jBridgeHandlerTest.level = FINER -# do not log mail-init. (is done on INFO-level) because this would init. JUL before setErr() happens -javax.mail.level = WARNING # configure (initial) JUL levels differently to log4j-config (and use high levels here) log4j.Log4jBridgeHandlerTest.propagate1.nested1.level = SEVERE diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml index 61a4feedfd..01f0016352 100644 --- a/log4j-parent/pom.xml +++ b/log4j-parent/pom.xml @@ -136,7 +136,6 @@ <javax-activation.version>1.2.0</javax-activation.version> <javax-inject.version>1</javax-inject.version> <javax-jaxb.version>2.3.1</javax-jaxb.version> - <javax-mail.version>1.6.2</javax-mail.version> <javax-persistence.version>2.2</javax-persistence.version> <javax-servlet.version>4.0.1</javax-servlet.version> <javax-servlet-jsp.version>2.3.3</javax-servlet-jsp.version> @@ -706,18 +705,6 @@ <version>${javax-inject.version}</version> </dependency> - <dependency> - <groupId>com.sun.mail</groupId> - <artifactId>javax.mail</artifactId> - <version>${javax-mail.version}</version> - </dependency> - - <dependency> - <groupId>javax.mail</groupId> - <artifactId>javax.mail-api</artifactId> - <version>${javax-mail.version}</version> - </dependency> - <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> diff --git a/log4j-smtp/pom.xml b/log4j-smtp/pom.xml deleted file mode 100644 index 703773f06f..0000000000 --- a/log4j-smtp/pom.xml +++ /dev/null @@ -1,119 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Licensed to the Apache Software Foundation (ASF) under one or more - ~ contributor license agreements. See the NOTICE file distributed with - ~ this work for additional information regarding copyright ownership. - ~ The ASF licenses this file to you 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. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j</artifactId> - <version>${revision}</version> - <relativePath>../log4j-parent</relativePath> - </parent> - - <artifactId>log4j-smtp</artifactId> - <name>Apache Log4j SMTP</name> - <description>Apache Log4j Simple Mail Transfer Protocol (SMTP) Appender.</description> - <properties> - <log4jParentDir>${basedir}/..</log4jParentDir> - <docLabel>Log4j SMTP Appender Documentation</docLabel> - <projectDir>/log4j-smtp</projectDir> - - <!-- - ~ OSGi and JPMS options - --> - <bnd-extra-module-options> - <!-- Filebased module names must be `static` --> - javax.mail.api;substitute="javax.mail-api";static=true;transitive=false - </bnd-extra-module-options> - </properties> - - <dependencies> - <!-- Required for SMTPAppender --> - <dependency> - <groupId>javax.activation</groupId> - <artifactId>javax.activation-api</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>javax.mail</groupId> - <artifactId>javax.mail-api</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-core</artifactId> - </dependency> - <dependency> - <groupId>com.sun.activation</groupId> - <artifactId>javax.activation</artifactId> - <scope>runtime</scope> - </dependency> - <dependency> - <groupId>com.sun.mail</groupId> - <artifactId>javax.mail</artifactId> - <scope>runtime</scope> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-api-test</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-core-test</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.lmax</groupId> - <artifactId>disruptor</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-engine</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.junit.vintage</groupId> - <artifactId>junit-vintage-engine</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <annotationProcessorPaths combine.children="append"> - <path> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-plugin-processor</artifactId> - <version>${project.version}</version> - </path> - </annotationProcessorPaths> - </configuration> - </plugin> - </plugins> - </build> -</project> diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/MimeMessageBuilder.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/MimeMessageBuilder.java deleted file mode 100644 index b6c935e4cc..0000000000 --- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/MimeMessageBuilder.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp; - -import java.nio.charset.StandardCharsets; - -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - -import org.apache.logging.log4j.plugins.util.Builder; - -/** - * Builder for {@link MimeMessage} instances. - */ -public class MimeMessageBuilder implements Builder<MimeMessage> { - private final MimeMessage message; - - public MimeMessageBuilder(final Session session) { - message = new MimeMessage(session); - } - - public MimeMessageBuilder setFrom(final String from) throws MessagingException { - final InternetAddress address = parseAddress(from); - - if (null != address) { - message.setFrom(address); - } else { - try { - message.setFrom(); - } catch (final Exception ex) { - message.setFrom((InternetAddress) null); - } - } - return this; - } - - public MimeMessageBuilder setReplyTo(final String replyTo) throws MessagingException { - final InternetAddress[] addresses = parseAddresses(replyTo); - - if (null != addresses) { - message.setReplyTo(addresses); - } - return this; - } - - public MimeMessageBuilder setRecipients(final Message.RecipientType recipientType, final String recipients) - throws MessagingException { - final InternetAddress[] addresses = parseAddresses(recipients); - - if (null != addresses) { - message.setRecipients(recipientType, addresses); - } - return this; - } - - public MimeMessageBuilder setSubject(final String subject) throws MessagingException { - if (subject != null) { - message.setSubject(subject, StandardCharsets.UTF_8.name()); - } - return this; - } - - @Override - public MimeMessage build() { - return message; - } - - private static InternetAddress parseAddress(final String address) throws AddressException { - return address == null ? null : new InternetAddress(address); - } - - private static InternetAddress[] parseAddresses(final String addresses) throws AddressException { - return addresses == null ? null : InternetAddress.parse(addresses, true); - } -} diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java deleted file mode 100644 index a96a2f8d45..0000000000 --- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpAppender.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp.appender; - -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.config.Property; -import org.apache.logging.log4j.core.filter.ThresholdFilter; -import org.apache.logging.log4j.core.layout.HtmlLayout; -import org.apache.logging.log4j.core.net.ssl.SslConfiguration; -import org.apache.logging.log4j.plugins.Configurable; -import org.apache.logging.log4j.plugins.Plugin; -import org.apache.logging.log4j.plugins.PluginAttribute; -import org.apache.logging.log4j.plugins.PluginElement; -import org.apache.logging.log4j.plugins.PluginFactory; -import org.apache.logging.log4j.plugins.validation.constraints.ValidPort; - -/** - * Send an e-mail when a specific logging event occurs, typically on errors or - * fatal errors. - * - * <p> - * The number of logging events delivered in this e-mail depend on the value of - * <b>BufferSize</b> option. The <code>SmtpAppender</code> keeps only the last - * <code>BufferSize</code> logging events in its cyclic buffer. This keeps - * memory requirements at a reasonable level while still delivering useful - * application context. - * - * By default, an email message will formatted as HTML. This can be modified by - * setting a layout for the appender. - * - * By default, an email message will be sent when an ERROR or higher severity - * message is appended. This can be modified by setting a filter for the - * appender. - */ -@Configurable(elementType = Appender.ELEMENT_TYPE, printObject = true) -@Plugin("SMTP") -public final class SmtpAppender extends AbstractAppender { - - private static final int DEFAULT_BUFFER_SIZE = 512; - - /** The SMTP Manager */ - private final SmtpManager manager; - - private SmtpAppender(final String name, final Filter filter, final Layout layout, final boolean ignoreExceptions, - Property[] properties, final SmtpManager manager) { - super(name, filter, layout, ignoreExceptions, properties); - this.manager = manager; - } - - /** - * @since 2.13.2 - */ - public static class Builder extends AbstractAppender.Builder<Builder> - implements org.apache.logging.log4j.plugins.util.Builder<SmtpAppender> { - @PluginAttribute - private String to; - - @PluginAttribute - private String cc; - - @PluginAttribute - private String bcc; - - @PluginAttribute - private String from; - - @PluginAttribute - private String replyTo; - - @PluginAttribute - private String subject; - - @PluginAttribute - private String smtpProtocol = "smtp"; - - @PluginAttribute - private String smtpHost; - - @PluginAttribute - @ValidPort - private int smtpPort; - - @PluginAttribute - private String smtpUsername; - - @PluginAttribute(sensitive = true) - private String smtpPassword; - - @PluginAttribute - private boolean smtpDebug; - - @PluginAttribute - private int bufferSize = DEFAULT_BUFFER_SIZE; - - @PluginElement("SSL") - private SslConfiguration sslConfiguration; - - /** - * Comma-separated list of recipient email addresses. - */ - public Builder setTo(final String to) { - this.to = to; - return this; - } - - /** - * Comma-separated list of CC email addresses. - */ - public Builder setCc(final String cc) { - this.cc = cc; - return this; - } - - /** - * Comma-separated list of BCC email addresses. - */ - public Builder setBcc(final String bcc) { - this.bcc = bcc; - return this; - } - - /** - * Email address of the sender. - */ - public Builder setFrom(final String from) { - this.from = from; - return this; - } - - /** - * Comma-separated list of Reply-To email addresses. - */ - public Builder setReplyTo(final String replyTo) { - this.replyTo = replyTo; - return this; - } - - /** - * Subject template for the email messages. - * @see org.apache.logging.log4j.core.layout.PatternLayout - */ - public Builder setSubject(final String subject) { - this.subject = subject; - return this; - } - - /** - * Transport protocol to use for SMTP such as "smtp" or "smtps". Defaults to "smtp". - */ - public Builder setSmtpProtocol(final String smtpProtocol) { - this.smtpProtocol = smtpProtocol; - return this; - } - - /** - * Host name of SMTP server to send messages through. - */ - public Builder setSmtpHost(final String smtpHost) { - this.smtpHost = smtpHost; - return this; - } - - /** - * Port number of SMTP server to send messages through. - */ - public Builder setSmtpPort(final int smtpPort) { - this.smtpPort = smtpPort; - return this; - } - - /** - * Username to authenticate with SMTP server. - */ - public Builder setSmtpUsername(final String smtpUsername) { - this.smtpUsername = smtpUsername; - return this; - } - - /** - * Password to authenticate with SMTP server. - */ - public Builder setSmtpPassword(final String smtpPassword) { - this.smtpPassword = smtpPassword; - return this; - } - - /** - * Enables or disables mail session debugging on STDOUT. Disabled by default. - */ - public Builder setSmtpDebug(final boolean smtpDebug) { - this.smtpDebug = smtpDebug; - return this; - } - - /** - * Number of log events to buffer before sending an email. Defaults to {@value #DEFAULT_BUFFER_SIZE}. - */ - public Builder setBufferSize(final int bufferSize) { - this.bufferSize = bufferSize; - return this; - } - - /** - * Specifies an SSL configuration for smtps connections. - */ - public Builder setSslConfiguration(final SslConfiguration sslConfiguration) { - this.sslConfiguration = sslConfiguration; - return this; - } - - @Override - public SmtpAppender build() { - if (getLayout() == null) { - setLayout(HtmlLayout.createDefaultLayout()); - } - if (getFilter() == null) { - setFilter(ThresholdFilter.createFilter(null, null, null)); - } - final SmtpManager smtpManager = SmtpManager.getSmtpManager(getConfiguration(), to, cc, bcc, from, replyTo, - subject, smtpProtocol, smtpHost, smtpPort, smtpUsername, smtpPassword, smtpDebug, - getFilter().toString(), bufferSize, sslConfiguration); - return new SmtpAppender(getName(), getFilter(), getLayout(), isIgnoreExceptions(), getPropertyArray(), smtpManager); - } - } - - /** - * @since 2.13.2 - */ - @PluginFactory - public static Builder newBuilder() { - return new Builder(); - } - - /** - * Capture all events in CyclicBuffer. - * @param event The Log event. - * @return true if the event should be filtered. - */ - @Override - public boolean isFiltered(final LogEvent event) { - final boolean filtered = super.isFiltered(event); - if (filtered) { - manager.add(event); - } - return filtered; - } - - /** - * Perform SmtpAppender specific appending actions, mainly adding the event - * to a cyclic buffer and checking if the event triggers an e-mail to be - * sent. - * @param event The Log event. - */ - @Override - public void append(final LogEvent event) { - manager.sendEvents(getLayout(), event); - } -} diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpManager.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpManager.java deleted file mode 100644 index d6182ece7d..0000000000 --- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/SmtpManager.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp.appender; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; -import java.util.Properties; - -import javax.activation.DataSource; -import javax.mail.Authenticator; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetHeaders; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import javax.mail.internet.MimeUtility; -import javax.mail.util.ByteArrayDataSource; -import javax.net.ssl.SSLSocketFactory; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.apache.logging.log4j.LoggingException; -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.AbstractManager; -import org.apache.logging.log4j.core.appender.ManagerFactory; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.layout.AbstractStringLayout.Serializer; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.apache.logging.log4j.core.net.ssl.SslConfiguration; -import org.apache.logging.log4j.core.util.CyclicBuffer; -import org.apache.logging.log4j.core.util.NetUtils; -import org.apache.logging.log4j.smtp.MimeMessageBuilder; -import org.apache.logging.log4j.util.Strings; - -/** - * Manager for sending SMTP events. - */ -public class SmtpManager extends AbstractManager { - private static final SMTPManagerFactory FACTORY = new SMTPManagerFactory(); - - private final Session session; - - private final CyclicBuffer<LogEvent> buffer; - - private volatile MimeMessage message; - - private final FactoryData data; - - private static MimeMessage createMimeMessage(final FactoryData data, final Session session, final LogEvent appendEvent) - throws MessagingException { - return new MimeMessageBuilder(session).setFrom(data.from).setReplyTo(data.replyto) - .setRecipients(Message.RecipientType.TO, data.to).setRecipients(Message.RecipientType.CC, data.cc) - .setRecipients(Message.RecipientType.BCC, data.bcc).setSubject(data.subject.toSerializable(appendEvent)) - .build(); - } - - protected SmtpManager(final String name, final Session session, final MimeMessage message, - final FactoryData data) { - super(null, name); - this.session = session; - this.message = message; - this.data = data; - this.buffer = new CyclicBuffer<>(LogEvent.class, data.numElements); - } - - public void add(final LogEvent event) { - buffer.add(event.toImmutable()); - } - - public static SmtpManager getSmtpManager( - final Configuration config, - final String to, final String cc, final String bcc, - final String from, final String replyTo, - final String subject, String protocol, final String host, - final int port, final String username, final String password, - final boolean isDebug, final String filterName, final int numElements, - final SslConfiguration sslConfiguration) { - if (Strings.isEmpty(protocol)) { - protocol = "smtp"; - } - - final String name = createManagerName(to, cc, bcc, from, replyTo, subject, protocol, host, port, username, isDebug, filterName); - final Serializer subjectSerializer = PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(subject).build(); - - return getManager(name, FACTORY, new FactoryData(to, cc, bcc, from, replyTo, subjectSerializer, - protocol, host, port, username, password, isDebug, numElements, sslConfiguration)); - - } - - /** - * Creates a unique-per-configuration name for an smtp manager using the specified the parameters.<br> - * Using such a name allows us to maintain singletons per unique configurations. - * - * @return smtp manager name - */ - static String createManagerName( - final String to, - final String cc, - final String bcc, - final String from, - final String replyTo, - final String subject, - final String protocol, - final String host, - final int port, - final String username, - final boolean isDebug, - final String filterName) { - - final StringBuilder sb = new StringBuilder(); - - if (to != null) { - sb.append(to); - } - sb.append(':'); - if (cc != null) { - sb.append(cc); - } - sb.append(':'); - if (bcc != null) { - sb.append(bcc); - } - sb.append(':'); - if (from != null) { - sb.append(from); - } - sb.append(':'); - if (replyTo != null) { - sb.append(replyTo); - } - sb.append(':'); - if (subject != null) { - sb.append(subject); - } - sb.append(':'); - sb.append(protocol).append(':').append(host).append(':').append(port).append(':'); - if (username != null) { - sb.append(username); - } - sb.append(isDebug ? ":debug:" : "::"); - sb.append(filterName); - - return "SMTP:" + sb.toString(); - } - - /** - * Send the contents of the cyclic buffer as an e-mail message. - * @param layout The layout for formatting the events. - * @param appendEvent The event that triggered the send. - */ - public void sendEvents(final Layout layout, final LogEvent appendEvent) { - if (message == null) { - connect(appendEvent); - } - try { - final LogEvent[] priorEvents = removeAllBufferedEvents(); - // LOG4J-310: log appendEvent even if priorEvents is empty - - final byte[] rawBytes = formatContentToBytes(priorEvents, appendEvent, layout); - - final String contentType = layout.getContentType(); - final String encoding = getEncoding(rawBytes, contentType); - final byte[] encodedBytes = encodeContentToBytes(rawBytes, encoding); - - final InternetHeaders headers = getHeaders(contentType, encoding); - final MimeMultipart mp = getMimeMultipart(encodedBytes, headers); - - final String subject = data.subject.toSerializable(appendEvent); - - sendMultipartMessage(message, mp, subject); - } catch (final MessagingException | IOException | RuntimeException e) { - logError("Caught exception while sending e-mail notification.", e); - throw new LoggingException("Error occurred while sending email", e); - } - } - - LogEvent[] removeAllBufferedEvents() { - return buffer.removeAll(); - } - - protected byte[] formatContentToBytes(final LogEvent[] priorEvents, final LogEvent appendEvent, - final Layout layout) throws IOException { - final ByteArrayOutputStream raw = new ByteArrayOutputStream(); - writeContent(priorEvents, appendEvent, layout, raw); - return raw.toByteArray(); - } - - private void writeContent(final LogEvent[] priorEvents, final LogEvent appendEvent, final Layout layout, - final ByteArrayOutputStream out) - throws IOException { - writeHeader(layout, out); - writeBuffer(priorEvents, appendEvent, layout, out); - writeFooter(layout, out); - } - - protected void writeHeader(final Layout layout, final OutputStream out) throws IOException { - final byte[] header = layout.getHeader(); - if (header != null) { - out.write(header); - } - } - - protected void writeBuffer(final LogEvent[] priorEvents, final LogEvent appendEvent, final Layout layout, - final OutputStream out) throws IOException { - for (final LogEvent priorEvent : priorEvents) { - final byte[] bytes = layout.toByteArray(priorEvent); - out.write(bytes); - } - - final byte[] bytes = layout.toByteArray(appendEvent); - out.write(bytes); - } - - protected void writeFooter(final Layout layout, final OutputStream out) throws IOException { - final byte[] footer = layout.getFooter(); - if (footer != null) { - out.write(footer); - } - } - - protected String getEncoding(final byte[] rawBytes, final String contentType) { - final DataSource dataSource = new ByteArrayDataSource(rawBytes, contentType); - return MimeUtility.getEncoding(dataSource); - } - - protected byte[] encodeContentToBytes(final byte[] rawBytes, final String encoding) - throws MessagingException, IOException { - final ByteArrayOutputStream encoded = new ByteArrayOutputStream(); - encodeContent(rawBytes, encoding, encoded); - return encoded.toByteArray(); - } - - protected void encodeContent(final byte[] bytes, final String encoding, final ByteArrayOutputStream out) - throws MessagingException, IOException { - try (final OutputStream encoder = MimeUtility.encode(out, encoding)) { - encoder.write(bytes); - } - } - - protected InternetHeaders getHeaders(final String contentType, final String encoding) { - final InternetHeaders headers = new InternetHeaders(); - headers.setHeader("Content-Type", contentType + "; charset=UTF-8"); - headers.setHeader("Content-Transfer-Encoding", encoding); - return headers; - } - - protected MimeMultipart getMimeMultipart(final byte[] encodedBytes, final InternetHeaders headers) - throws MessagingException { - final MimeMultipart mp = new MimeMultipart(); - final MimeBodyPart part = new MimeBodyPart(headers, encodedBytes); - mp.addBodyPart(part); - return mp; - } - - @SuppressFBWarnings( - value = "SMTP_HEADER_INJECTION", - justification = "False positive, since MimeMessage#setSubject does actually escape new lines." - ) - protected void sendMultipartMessage(final MimeMessage msg, final MimeMultipart mp, final String subject) throws MessagingException { - synchronized (msg) { - msg.setContent(mp); - msg.setSentDate(new Date()); - msg.setSubject(subject); - Transport.send(msg); - } - } - - /** - * Factory data. - */ - private static class FactoryData { - private final String to; - private final String cc; - private final String bcc; - private final String from; - private final String replyto; - private final Serializer subject; - private final String protocol; - private final String host; - private final int port; - private final String username; - private final String password; - private final boolean isDebug; - private final int numElements; - private final SslConfiguration sslConfiguration; - - public FactoryData(final String to, final String cc, final String bcc, final String from, final String replyTo, - final Serializer subjectSerializer, final String protocol, final String host, final int port, - final String username, final String password, final boolean isDebug, final int numElements, - final SslConfiguration sslConfiguration) { - this.to = to; - this.cc = cc; - this.bcc = bcc; - this.from = from; - this.replyto = replyTo; - this.subject = subjectSerializer; - this.protocol = protocol; - this.host = host; - this.port = port; - this.username = username; - this.password = password; - this.isDebug = isDebug; - this.numElements = numElements; - this.sslConfiguration = sslConfiguration; - } - } - - private synchronized void connect(final LogEvent appendEvent) { - if (message != null) { - return; - } - try { - message = createMimeMessage(data, session, appendEvent); - } catch (final MessagingException e) { - logError("Could not set SmtpAppender message options", e); - message = null; - } - } - - /** - * Factory to create the SMTP Manager. - */ - private static class SMTPManagerFactory implements ManagerFactory<SmtpManager, FactoryData> { - - @Override - public SmtpManager createManager(final String name, final FactoryData data) { - final String prefix = "mail." + data.protocol; - - final Properties properties = System.getProperties(); - properties.setProperty("mail.transport.protocol", data.protocol); - if (properties.getProperty("mail.host") == null) { - // Prevent an UnknownHostException in Java 7 - properties.setProperty("mail.host", NetUtils.getLocalHostname()); - } - - if (null != data.host) { - properties.setProperty(prefix + ".host", data.host); - } - if (data.port > 0) { - properties.setProperty(prefix + ".port", String.valueOf(data.port)); - } - - final Authenticator authenticator = buildAuthenticator(data.username, data.password); - if (null != authenticator) { - properties.setProperty(prefix + ".auth", "true"); - } - - if (data.protocol.equals("smtps")) { - final SslConfiguration sslConfiguration = data.sslConfiguration; - if (sslConfiguration != null) { - final SSLSocketFactory sslSocketFactory = sslConfiguration.getSslSocketFactory(); - properties.put(prefix + ".ssl.socketFactory", sslSocketFactory); - properties.setProperty(prefix + ".ssl.checkserveridentity", Boolean.toString(sslConfiguration.isVerifyHostName())); - } - } - - final Session session = Session.getInstance(properties, authenticator); - session.setProtocolForAddress("rfc822", data.protocol); - session.setDebug(data.isDebug); - return new SmtpManager(name, session, null, data); - } - - private Authenticator buildAuthenticator(final String username, final String password) { - if (null != password && null != username) { - return new Authenticator() { - private final PasswordAuthentication passwordAuthentication = - new PasswordAuthentication(username, password); - - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return passwordAuthentication; - } - }; - } - return null; - } - } -} diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/package-info.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/package-info.java deleted file mode 100644 index 715be0fec2..0000000000 --- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/appender/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -@Export -@Version("1.0.0") -package org.apache.logging.log4j.smtp.appender; - -import org.osgi.annotation.bundle.Export; -import org.osgi.annotation.versioning.Version; diff --git a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/package-info.java b/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/package-info.java deleted file mode 100644 index 91c84dbb67..0000000000 --- a/log4j-smtp/src/main/java/org/apache/logging/log4j/smtp/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -@Export -@Version("1.0.0") -package org.apache.logging.log4j.smtp; - -import org.osgi.annotation.bundle.Export; -import org.osgi.annotation.versioning.Version; diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SimpleSmtpServer.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SimpleSmtpServer.java deleted file mode 100644 index d96b1c5dec..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SimpleSmtpServer.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.logging.log4j.util.Strings; - -/** - * Dummy SMTP server for testing purposes. - * - * @todo constructor allowing user to pass preinitialized ServerSocket - */ -public class SimpleSmtpServer implements Runnable { - /** - * Stores all of the email received since this instance started up. - */ - private final List<SmtpMessage> receivedMail; - - /** - * Default SMTP port is 25. - */ - public static final int DEFAULT_SMTP_PORT = 25; - - /** - * Indicates whether this server is stopped or not. - */ - private volatile boolean stopped = true; - - /** - * Handle to the server socket this server listens to. - */ - private ServerSocket serverSocket; - - /** - * Port the server listens on - set to the default SMTP port initially. - */ - private int port = DEFAULT_SMTP_PORT; - - /** - * Timeout listening on server socket. - */ - private static final int TIMEOUT = 500; - - /** - * Constructor. - * - * @param port port number - */ - public SimpleSmtpServer(final int port) { - receivedMail = new ArrayList<>(); - this.port = port; - } - - /** - * Main loop of the SMTP server. - */ - @Override - public void run() { - stopped = false; - try { - try { - serverSocket = new ServerSocket(port); - serverSocket.setSoTimeout(TIMEOUT); // Block for maximum of 1.5 seconds - } finally { - synchronized (this) { - // Notify when server socket has been created - notifyAll(); - } - } - - // Server: loop until stopped - while (!isStopped()) { - // Start server socket and listen for client connections - Socket socket = null; - try { - socket = serverSocket.accept(); - } catch (final Exception e) { - if (socket != null) { - socket.close(); - } - continue; // Non-blocking socket timeout occurred: try accept() again - } - - // Get the input and output streams - final BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); - final PrintWriter out = new PrintWriter(socket.getOutputStream()); - - synchronized (this) { - /* - * We synchronize over the handle method and the list update because the client call completes - * inside the handle method and we have to prevent the client from reading the list until we've - * updated it. For higher concurrency, we could just change handle to return void and update the - * list inside the method to limit the duration that we hold the lock. - */ - final List<SmtpMessage> msgs = handleTransaction(out, input); - receivedMail.addAll(msgs); - } - socket.close(); - } - } catch (final Exception e) { - /** @todo Should throw an appropriate exception here. */ - e.printStackTrace(); - } finally { - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (final IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Check if the server has been placed in a stopped state. Allows another thread to - * stop the server safely. - * - * @return true if the server has been sent a stop signal, false otherwise - */ - public synchronized boolean isStopped() { - return stopped; - } - - /** - * Stops the server. Server is shutdown after processing of the current request is complete. - */ - public synchronized void stop() { - // Mark us closed - stopped = true; - try { - // Kick the server accept loop - serverSocket.close(); - } catch (final IOException e) { - // Ignore - } - } - - /** - * Handle an SMTP transaction, i.e. all activity between initial connect and QUIT command. - * - * @param out output stream - * @param input input stream - * @return List of SmtpMessage - * @throws IOException - */ - private List<SmtpMessage> handleTransaction(final PrintWriter out, final BufferedReader input) throws IOException { - // Initialize the state machine - SmtpState smtpState = SmtpState.CONNECT; - final SmtpRequest smtpRequest = new SmtpRequest(SmtpActionType.CONNECT, Strings.EMPTY, smtpState); - - // Execute the connection request - final SmtpResponse smtpResponse = smtpRequest.execute(); - - // Send initial response - sendResponse(out, smtpResponse); - smtpState = smtpResponse.getNextState(); - - final List<SmtpMessage> msgList = new ArrayList<>(); - SmtpMessage msg = new SmtpMessage(); - - while (smtpState != SmtpState.CONNECT) { - final String line = input.readLine(); - - if (line == null) { - break; - } - - // Create request from client input and current state - final SmtpRequest request = SmtpRequest.createRequest(line, smtpState); - // Execute request and create response object - final SmtpResponse response = request.execute(); - // Move to next internal state - smtpState = response.getNextState(); - // Send response to client - sendResponse(out, response); - - // Store input in message - final String params = request.getParams(); - msg.store(response, params); - - // If message reception is complete save it - if (smtpState == SmtpState.QUIT) { - msgList.add(msg); - msg = new SmtpMessage(); - } - } - - return msgList; - } - - /** - * Send response to client. - * - * @param out socket output stream - * @param smtpResponse response object - */ - private static void sendResponse(final PrintWriter out, final SmtpResponse smtpResponse) { - if (smtpResponse.getCode() > 0) { - final int code = smtpResponse.getCode(); - final String message = smtpResponse.getMessage(); - out.print(code + " " + message + "\r\n"); - out.flush(); - } - } - - /** - * Get email received by this instance since start up. - * - * @return List of String - */ - public synchronized Iterator<SmtpMessage> getReceivedEmail() { - return receivedMail.iterator(); - } - - /** - * Get the number of messages received. - * - * @return size of received email list - */ - public synchronized int getReceivedEmailSize() { - return receivedMail.size(); - } - - /** - * Creates an instance of SimpleSmtpServer and starts it. Will listen on the default port. - * - * @return a reference to the SMTP server - */ - public static SimpleSmtpServer start() { - return start(DEFAULT_SMTP_PORT); - } - - /** - * Creates an instance of SimpleSmtpServer and starts it. - * - * @param port port number the server should listen to - * @return a reference to the SMTP server - */ - public static SimpleSmtpServer start(final int port) { - final SimpleSmtpServer server = new SimpleSmtpServer(port); - final Thread t = new Thread(server); - - - // Block until the server socket is created - synchronized (server) { - t.start(); - try { - server.wait(); - } catch (final InterruptedException e) { - // Ignore don't care. - } - } - return server; - } - -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpActionType.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpActionType.java deleted file mode 100644 index b7245b435c..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpActionType.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -/** - * Represents an SMTP action or command. - */ -public final class SmtpActionType { - /** - * Internal value for the action type. - */ - private final byte value; - - /** - * Internal representation of the CONNECT action. - */ - private static final byte CONNECT_BYTE = (byte) 1; - /** - * Internal representation of the EHLO action. - */ - private static final byte EHLO_BYTE = (byte) 2; - /** - * Internal representation of the MAIL FROM action. - */ - private static final byte MAIL_BYTE = (byte) 3; - /** - * Internal representation of the RCPT action. - */ - private static final byte RCPT_BYTE = (byte) 4; - /** - * Internal representation of the DATA action. - */ - private static final byte DATA_BYTE = (byte) 5; - /** - * Internal representation of the DATA END (.) action. - */ - private static final byte DATA_END_BYTE = (byte) 6; - /** - * Internal representation of the QUIT action. - */ - private static final byte QUIT_BYTE = (byte) 7; - /** - * Internal representation of an unrecognized action: body text gets this action type. - */ - private static final byte UNREC_BYTE = (byte) 8; - /** - * Internal representation of the blank line action: separates headers and body text. - */ - private static final byte BLANK_LINE_BYTE = (byte) 9; - - /** - * Internal representation of the stateless RSET action. - */ - private static final byte RSET_BYTE = (byte) -1; - /** - * Internal representation of the stateless VRFY action. - */ - private static final byte VRFY_BYTE = (byte) -2; - /** - * Internal representation of the stateless EXPN action. - */ - private static final byte EXPN_BYTE = (byte) -3; - /** - * Internal representation of the stateless HELP action. - */ - private static final byte HELP_BYTE = (byte) -4; - /** - * Internal representation of the stateless NOOP action. - */ - private static final byte NOOP_BYTE = (byte) -5; - - /** - * CONNECT action. - */ - public static final SmtpActionType CONNECT = new SmtpActionType(CONNECT_BYTE); - /** - * EHLO action. - */ - public static final SmtpActionType EHLO = new SmtpActionType(EHLO_BYTE); - /** - * MAIL action. - */ - public static final SmtpActionType MAIL = new SmtpActionType(MAIL_BYTE); - /** - * RCPT action. - */ - public static final SmtpActionType RCPT = new SmtpActionType(RCPT_BYTE); - /** - * DATA action. - */ - public static final SmtpActionType DATA = new SmtpActionType(DATA_BYTE); - /** - * "." action. - */ - public static final SmtpActionType DATA_END = new SmtpActionType(DATA_END_BYTE); - /** - * Body text action. - */ - public static final SmtpActionType UNRECOG = new SmtpActionType(UNREC_BYTE); - /** - * QUIT action. - */ - public static final SmtpActionType QUIT = new SmtpActionType(QUIT_BYTE); - /** - * Header/body separator action. - */ - public static final SmtpActionType BLANK_LINE = new SmtpActionType(BLANK_LINE_BYTE); - - /** - * Stateless RSET action. - */ - public static final SmtpActionType RSET = new SmtpActionType(RSET_BYTE); - /** - * Stateless VRFY action. - */ - public static final SmtpActionType VRFY = new SmtpActionType(VRFY_BYTE); - /** - * Stateless EXPN action. - */ - public static final SmtpActionType EXPN = new SmtpActionType(EXPN_BYTE); - /** - * Stateless HELP action. - */ - public static final SmtpActionType HELP = new SmtpActionType(HELP_BYTE); - /** - * Stateless NOOP action. - */ - public static final SmtpActionType NOOP = new SmtpActionType(NOOP_BYTE); - - /** - * Create a new SMTP action type. Private to ensure no invalid values. - * - * @param value one of the _BYTE values - */ - private SmtpActionType(final byte value) { - this.value = value; - } - - /** - * Indicates whether the action is stateless or not. - * - * @return true iff the action is stateless - */ - public boolean isStateless() { - return value < 0; - } - - /** - * String representation of this SMTP action type. - * - * @return a String - */ - @Override - public String toString() { - switch (value) { - case CONNECT_BYTE: - return "Connect"; - case EHLO_BYTE: - return "EHLO"; - case MAIL_BYTE: - return "MAIL"; - case RCPT_BYTE: - return "RCPT"; - case DATA_BYTE: - return "DATA"; - case DATA_END_BYTE: - return "."; - case QUIT_BYTE: - return "QUIT"; - case RSET_BYTE: - return "RSET"; - case VRFY_BYTE: - return "VRFY"; - case EXPN_BYTE: - return "EXPN"; - case HELP_BYTE: - return "HELP"; - case NOOP_BYTE: - return "NOOP"; - case UNREC_BYTE: - return "Unrecognized command / data"; - case BLANK_LINE_BYTE: - return "Blank line"; - default: - return "Unknown"; - } - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpMessage.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpMessage.java deleted file mode 100644 index e21b6ba205..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpMessage.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Container for a complete SMTP message - headers and message body. - */ -public class SmtpMessage { - /** - * Headers: Map of List of String hashed on header name. - */ - private final Map<String, List<String>> headers; - /** - * Message body. - */ - private final StringBuffer body; - - /** - * Constructor. Initializes headers Map and body buffer. - */ - public SmtpMessage() { - headers = new HashMap<>(10); - body = new StringBuffer(); - } - - /** - * Update the headers or body depending on the SmtpResponse object and line of input. - * - * @param response SmtpResponse object - * @param params remainder of input line after SMTP command has been removed - */ - public void store(final SmtpResponse response, final String params) { - if (params != null) { - if (SmtpState.DATA_HDR.equals(response.getNextState())) { - final int headerNameEnd = params.indexOf(':'); - if (headerNameEnd >= 0) { - final String name = params.substring(0, headerNameEnd).trim(); - final String value = params.substring(headerNameEnd + 1).trim(); - addHeader(name, value); - } - } else if (SmtpState.DATA_BODY == response.getNextState()) { - body.append(params); - } - } - } - - /** - * Get an Iterator over the header names. - * - * @return an Iterator over the set of header names (String) - */ - public Iterator<String> getHeaderNames() { - final Set<String> nameSet = headers.keySet(); - return nameSet.iterator(); - } - - /** - * Get the value(s) associated with the given header name. - * - * @param name header name - * @return value(s) associated with the header name - */ - public String[] getHeaderValues(final String name) { - final List<String> values = headers.get(name); - if (values == null) { - return new String[0]; - } - return values.toArray(new String[values.size()]); - } - - /** - * Get the first values associated with a given header name. - * - * @param name header name - * @return first value associated with the header name - */ - public String getHeaderValue(final String name) { - final List<String> values = headers.get(name); - if (values == null) { - return null; - } - final Iterator<String> iterator = values.iterator(); - return iterator.hasNext() ? iterator.next() : null; - } - - /** - * Get the message body. - * - * @return message body - */ - public String getBody() { - return body.toString(); - } - - /** - * Adds a header to the Map. - * - * @param name header name - * @param value header value - */ - private void addHeader(final String name, final String value) { - List<String> valueList = headers.get(name); - if (valueList == null) { - valueList = new ArrayList<>(1); - headers.put(name, valueList); - } - valueList.add(value); - } - - /** - * String representation of the SmtpMessage. - * - * @return a String - */ - @Override - public String toString() { - final StringBuilder msg = new StringBuilder(); - for (final Map.Entry<String, List<String>> entry : headers.entrySet()) { - final String name = entry.getKey(); - final List<String> values = entry.getValue(); - for (final String value : values) { - msg.append(name); - msg.append(": "); - msg.append(value); - msg.append('\n'); - } - } - msg.append('\n'); - msg.append(body); - msg.append('\n'); - return msg.toString(); - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpRequest.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpRequest.java deleted file mode 100644 index fd65d971e3..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpRequest.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -import org.apache.logging.log4j.util.Strings; - -/** - * Contains an SMTP client request. Handles state transitions using the following state transition table. - * <PRE> - * -----------+------------------------------------------------------------------------------------------------- - * | State - * Action +-------------+-----------+-----------+--------------+---------------+---------------+------------ - * | CONNECT | GREET | MAIL | RCPT | DATA_HDR | DATA_BODY | QUIT - * -----------+-------------+-----------+-----------+--------------+---------------+---------------+------------ - * connect | 220/GREET | 503/GREET | 503/MAIL | 503/RCPT | 503/DATA_HDR | 503/DATA_BODY | 503/QUIT - * ehlo | 503/CONNECT | 250/MAIL | 503/MAIL | 503/RCPT | 503/DATA_HDR | 503/DATA_BODY | 503/QUIT - * mail | 503/CONNECT | 503/GREET | 250/RCPT | 503/RCPT | 503/DATA_HDR | 503/DATA_BODY | 250/RCPT - * rcpt | 503/CONNECT | 503/GREET | 503/MAIL | 250/RCPT | 503/DATA_HDR | 503/DATA_BODY | 503/QUIT - * data | 503/CONNECT | 503/GREET | 503/MAIL | 354/DATA_HDR | 503/DATA_HDR | 503/DATA_BODY | 503/QUIT - * data_end | 503/CONNECT | 503/GREET | 503/MAIL | 503/RCPT | 250/QUIT | 250/QUIT | 503/QUIT - * unrecog | 500/CONNECT | 500/GREET | 500/MAIL | 500/RCPT | ---/DATA_HDR | ---/DATA_BODY | 500/QUIT - * quit | 503/CONNECT | 503/GREET | 503/MAIL | 503/RCPT | 503/DATA_HDR | 503/DATA_BODY | 250/CONNECT - * blank_line | 503/CONNECT | 503/GREET | 503/MAIL | 503/RCPT | ---/DATA_BODY | ---/DATA_BODY | 503/QUIT - * rset | 250/GREET | 250/GREET | 250/GREET | 250/GREET | 250/GREET | 250/GREET | 250/GREET - * vrfy | 252/CONNECT | 252/GREET | 252/MAIL | 252/RCPT | 252/DATA_HDR | 252/DATA_BODY | 252/QUIT - * expn | 252/CONNECT | 252/GREET | 252/MAIL | 252/RCPT | 252/DATA_HDR | 252/DATA_BODY | 252/QUIT - * help | 211/CONNECT | 211/GREET | 211/MAIL | 211/RCPT | 211/DATA_HDR | 211/DATA_BODY | 211/QUIT - * noop | 250/CONNECT | 250/GREET | 250/MAIL | 250/RCPT | 250|DATA_HDR | 250/DATA_BODY | 250/QUIT - * </PRE> - */ -public class SmtpRequest { - /** - * SMTP action received from client. - */ - private final SmtpActionType action; - /** - * Current state of the SMTP state table. - */ - private final SmtpState state; - /** - * Additional information passed from the client with the SMTP action. - */ - private final String params; - - /** - * Create a new SMTP client request. - * - * @param actionType type of action/command - * @param params remainder of command line once command is removed - * @param state current SMTP server state - */ - public SmtpRequest(final SmtpActionType actionType, final String params, final SmtpState state) { - this.action = actionType; - this.state = state; - this.params = params; - } - - /** - * Execute the SMTP request returning a response. This method models the state transition table for the SMTP server. - * - * @return reponse to the request - */ - public SmtpResponse execute() { - SmtpResponse response = null; - if (action.isStateless()) { - if (SmtpActionType.EXPN == action || SmtpActionType.VRFY == action) { - response = new SmtpResponse(252, "Not supported", this.state); - } else if (SmtpActionType.HELP == action) { - response = new SmtpResponse(211, "No help available", this.state); - } else if (SmtpActionType.NOOP == action) { - response = new SmtpResponse(250, "OK", this.state); - } else if (SmtpActionType.VRFY == action) { - response = new SmtpResponse(252, "Not supported", this.state); - } else if (SmtpActionType.RSET == action) { - response = new SmtpResponse(250, "OK", SmtpState.GREET); - } else { - response = new SmtpResponse(500, "Command not recognized", this.state); - } - } else { // Stateful commands - if (SmtpActionType.CONNECT == action) { - if (SmtpState.CONNECT == state) { - response = new SmtpResponse(220, "localhost Dumbster SMTP service ready", SmtpState.GREET); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.EHLO == action) { - if (SmtpState.GREET == state) { - response = new SmtpResponse(250, "OK", SmtpState.MAIL); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.MAIL == action) { - if (SmtpState.MAIL == state || SmtpState.QUIT == state) { - response = new SmtpResponse(250, "OK", SmtpState.RCPT); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.RCPT == action) { - if (SmtpState.RCPT == state) { - response = new SmtpResponse(250, "OK", this.state); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.DATA == action) { - if (SmtpState.RCPT == state) { - response = new SmtpResponse(354, "Start mail input; end with <CRLF>.<CRLF>", SmtpState.DATA_HDR); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.UNRECOG == action) { - if (SmtpState.DATA_HDR == state || SmtpState.DATA_BODY == state) { - response = new SmtpResponse(-1, Strings.EMPTY, this.state); - } else { - response = new SmtpResponse(500, "Command not recognized", this.state); - } - } else if (SmtpActionType.DATA_END == action) { - if (SmtpState.DATA_HDR == state || SmtpState.DATA_BODY == state) { - response = new SmtpResponse(250, "OK", SmtpState.QUIT); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.BLANK_LINE == action) { - if (SmtpState.DATA_HDR == state) { - response = new SmtpResponse(-1, Strings.EMPTY, SmtpState.DATA_BODY); - } else if (SmtpState.DATA_BODY == state) { - response = new SmtpResponse(-1, Strings.EMPTY, this.state); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else if (SmtpActionType.QUIT == action) { - if (SmtpState.QUIT == state) { - response = new SmtpResponse(221, "localhost Dumbster service closing transmission channel", - SmtpState.CONNECT); - } else { - response = new SmtpResponse(503, "Bad sequence of commands: " + action, this.state); - } - } else { - response = new SmtpResponse(500, "Command not recognized", this.state); - } - } - return response; - } - - /** - * Create an SMTP request object given a line of the input stream from the client and the current internal state. - * - * @param s line of input - * @param state current state - * @return a populated SmtpRequest object - */ - public static SmtpRequest createRequest(final String s, final SmtpState state) { - SmtpActionType action = null; - String params = null; - - if (state == SmtpState.DATA_HDR) { - if (s.equals(".")) { - action = SmtpActionType.DATA_END; - } else if (s.length() < 1) { - action = SmtpActionType.BLANK_LINE; - } else { - action = SmtpActionType.UNRECOG; - params = s; - } - } else if (state == SmtpState.DATA_BODY) { - if (s.equals(".")) { - action = SmtpActionType.DATA_END; - } else { - action = SmtpActionType.UNRECOG; - if (s.length() < 1) { - params = "\n"; - } else { - params = s; - } - } - } else { - final String su = s.toUpperCase(); - if (su.startsWith("EHLO ") || su.startsWith("HELO")) { - action = SmtpActionType.EHLO; - params = s.substring(5); - } else if (su.startsWith("MAIL FROM:")) { - action = SmtpActionType.MAIL; - params = s.substring(10); - } else if (su.startsWith("RCPT TO:")) { - action = SmtpActionType.RCPT; - params = s.substring(8); - } else if (su.startsWith("DATA")) { - action = SmtpActionType.DATA; - } else if (su.startsWith("QUIT")) { - action = SmtpActionType.QUIT; - } else if (su.startsWith("RSET")) { - action = SmtpActionType.RSET; - } else if (su.startsWith("NOOP")) { - action = SmtpActionType.NOOP; - } else if (su.startsWith("EXPN")) { - action = SmtpActionType.EXPN; - } else if (su.startsWith("VRFY")) { - action = SmtpActionType.VRFY; - } else if (su.startsWith("HELP")) { - action = SmtpActionType.HELP; - } else { - action = SmtpActionType.UNRECOG; - } - } - - final SmtpRequest req = new SmtpRequest(action, params, state); - return req; - } - - /** - * Get the parameters of this request (remainder of command line once the command is removed. - * - * @return parameters - */ - public String getParams() { - return params; - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpResponse.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpResponse.java deleted file mode 100644 index 0a71dbb526..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpResponse.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -/** - * SMTP response container. - */ -public class SmtpResponse { - /** - * Response code - see RFC-2821. - */ - private final int code; - /** - * Response message. - */ - private final String message; - /** - * New state of the SMTP server once the request has been executed. - */ - private final SmtpState nextState; - - /** - * Constructor. - * - * @param code response code - * @param message response message - * @param next next state of the SMTP server - */ - public SmtpResponse(final int code, final String message, final SmtpState next) { - this.code = code; - this.message = message; - this.nextState = next; - } - - /** - * Get the response code. - * - * @return response code - */ - public int getCode() { - return code; - } - - /** - * Get the response message. - * - * @return response message - */ - public String getMessage() { - return message; - } - - /** - * Get the next SMTP server state. - * - * @return state - */ - public SmtpState getNextState() { - return nextState; - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpState.java b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpState.java deleted file mode 100644 index 74c5bd3bbf..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/SmtpState.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.dumbster.smtp; - -/** - * SMTP server state. - */ -public final class SmtpState { - /** - * Internal representation of the state. - */ - private final byte value; - - /** - * Internal representation of the CONNECT state. - */ - private static final byte CONNECT_BYTE = (byte) 1; - /** - * Internal representation of the GREET state. - */ - private static final byte GREET_BYTE = (byte) 2; - /** - * Internal representation of the MAIL state. - */ - private static final byte MAIL_BYTE = (byte) 3; - /** - * Internal representation of the RCPT state. - */ - private static final byte RCPT_BYTE = (byte) 4; - /** - * Internal representation of the DATA_HEADER state. - */ - private static final byte DATA_HEADER_BYTE = (byte) 5; - /** - * Internal representation of the DATA_BODY state. - */ - private static final byte DATA_BODY_BYTE = (byte) 6; - /** - * Internal representation of the QUIT state. - */ - private static final byte QUIT_BYTE = (byte) 7; - - /** - * CONNECT state: waiting for a client connection. - */ - public static final SmtpState CONNECT = new SmtpState(CONNECT_BYTE); - /** - * GREET state: wating for a ELHO message. - */ - public static final SmtpState GREET = new SmtpState(GREET_BYTE); - /** - * MAIL state: waiting for the MAIL FROM: command. - */ - public static final SmtpState MAIL = new SmtpState(MAIL_BYTE); - /** - * RCPT state: waiting for a RCPT <email address> command. - */ - public static final SmtpState RCPT = new SmtpState(RCPT_BYTE); - /** - * Waiting for headers. - */ - public static final SmtpState DATA_HDR = new SmtpState(DATA_HEADER_BYTE); - /** - * Processing body text. - */ - public static final SmtpState DATA_BODY = new SmtpState(DATA_BODY_BYTE); - /** - * End of client transmission. - */ - public static final SmtpState QUIT = new SmtpState(QUIT_BYTE); - - /** - * Create a new SmtpState object. Private to ensure that only valid states can be created. - * - * @param value one of the _BYTE values. - */ - private SmtpState(final byte value) { - this.value = value; - } - - /** - * String representation of this SmtpState. - * - * @return a String - */ - @Override - public String toString() { - switch (value) { - case CONNECT_BYTE: - return "CONNECT"; - case GREET_BYTE: - return "GREET"; - case MAIL_BYTE: - return "MAIL"; - case RCPT_BYTE: - return "RCPT"; - case DATA_HEADER_BYTE: - return "DATA_HDR"; - case DATA_BODY_BYTE: - return "DATA_BODY"; - case QUIT_BYTE: - return "QUIT"; - default: - return "Unknown"; - } - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/readme.txt b/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/readme.txt deleted file mode 100644 index aded490e72..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/dumbster/smtp/readme.txt +++ /dev/null @@ -1,4 +0,0 @@ -Dumbster was an open source project hosted at Sourceforge. Unfortunately, that project has not had any commits -to it since 2005. The code was copied here to be able to address a race condition in SimpleSmtpServer. - -Dumbster is Copyright 2004 Jason Paul Kitchen \ No newline at end of file diff --git a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java deleted file mode 100644 index f28b5797b9..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp.appender; - -import java.util.Iterator; - -import org.apache.logging.dumbster.smtp.SimpleSmtpServer; -import org.apache.logging.dumbster.smtp.SmtpMessage; -import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.core.test.AvailablePortFinder; -import org.apache.logging.log4j.core.test.junit.LoggerContextRule; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public class SmtpAppenderAsyncTest { - - private static int PORT; - - private SimpleSmtpServer smtpServer; - - @BeforeClass - public static void setupClass() { - PORT = AvailablePortFinder.getNextAvailable(); - System.setProperty("smtp.port", String.valueOf(PORT)); - } - - @Before - public void setup() { - smtpServer = SimpleSmtpServer.start(PORT); - } - - @Rule - public LoggerContextRule ctx = new LoggerContextRule("SmtpAppenderAsyncTest.xml"); - - @Test - public void testSync() { - testSmtpAppender(ctx.getLogger("sync")); - } - - @Test - public void testAsync() { - testSmtpAppender(ctx.getLogger("async")); - } - - private void testSmtpAppender(final Logger logger) { - ThreadContext.put("MDC1", "mdc1"); - logger.error("the message"); - ctx.getLoggerContext().stop(); - smtpServer.stop(); - - assertEquals(1, smtpServer.getReceivedEmailSize()); - final Iterator<SmtpMessage> messages = smtpServer.getReceivedEmail(); - final SmtpMessage email = messages.next(); - - assertEquals("[email protected]", email.getHeaderValue("To")); - assertEquals("[email protected]", email.getHeaderValue("From")); - assertEquals("[mdc1]", email.getHeaderValue("Subject")); - - final String body = email.getBody(); - if (!body.contains("Body:[mdc1]")) { - fail(body); - } - } - - @After - public void teardown() { - if (smtpServer != null) { - smtpServer.stop(); - } - } - - @AfterClass - public static void teardownClass() { - System.clearProperty("smtp.port"); - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java deleted file mode 100644 index 7caf33f305..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp.appender; - -import java.util.Iterator; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.internet.InternetAddress; - -import org.apache.logging.dumbster.smtp.SimpleSmtpServer; -import org.apache.logging.dumbster.smtp.SmtpMessage; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.DefaultConfiguration; -import org.apache.logging.log4j.core.test.AvailablePortFinder; -import org.apache.logging.log4j.core.test.categories.Appenders; -import org.apache.logging.log4j.smtp.MimeMessageBuilder; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import static org.junit.Assert.*; - -@Category(Appenders.Smtp.class) -public class SmtpAppenderTest { - - private static final String HOST = "localhost"; - - @Test - public void testMessageFactorySetFrom() throws MessagingException { - final MimeMessageBuilder builder = new MimeMessageBuilder(null); - final String address = "[email protected]"; - - assertNull(builder.build().getFrom()); - - builder.setFrom(null); - Address[] array = null; - final Address addr = InternetAddress.getLocalAddress(null); - if (addr != null) { - array = new Address[] { addr }; - } - assertArrayEquals(array, builder.build().getFrom()); - - builder.setFrom(address); - assertArrayEquals(new Address[] { new InternetAddress(address) }, - builder.build().getFrom()); - } - - @Test - public void testMessageFactorySetReplyTo() throws MessagingException { - final MimeMessageBuilder builder = new MimeMessageBuilder(null); - final String addresses = "[email protected],[email protected]"; - - assertNull(builder.build().getReplyTo()); - - builder.setReplyTo(null); - assertNull(builder.build().getReplyTo()); - - builder.setReplyTo(addresses); - assertArrayEquals(InternetAddress.parse(addresses), builder - .build().getReplyTo()); - } - - @Test - public void testMessageFactorySetRecipients() throws MessagingException { - final MimeMessageBuilder builder = new MimeMessageBuilder(null); - final String addresses = "[email protected],[email protected]"; - - assertNull(builder.build().getRecipients( - Message.RecipientType.TO)); - - builder.setRecipients(Message.RecipientType.TO, null); - assertNull(builder.build().getRecipients( - Message.RecipientType.TO)); - - builder.setRecipients(Message.RecipientType.TO, addresses); - assertArrayEquals(InternetAddress.parse(addresses), builder - .build().getRecipients(Message.RecipientType.TO)); - } - - @Test - public void testMessageFactorySetSubject() throws MessagingException { - final MimeMessageBuilder builder = new MimeMessageBuilder(null); - final String subject = "Test Subject"; - - assertNull(builder.build().getSubject()); - - builder.setSubject(null); - assertNull(builder.build().getSubject()); - - builder.setSubject(subject); - assertEquals(subject, builder.build().getSubject()); - } - - @Test - public void testDelivery() { - final String subjectKey = getClass().getName(); - final String subjectValue = "SubjectValue1"; - ThreadContext.put(subjectKey, subjectValue); - final int smtpPort = AvailablePortFinder.getNextAvailable(); - final SmtpAppender appender = SmtpAppender.newBuilder() - .setConfiguration(new DefaultConfiguration()) - .setName("Test") - .setTo("[email protected]") - .setCc("[email protected]") - .setBcc("[email protected]") - .setFrom("[email protected]") - .setReplyTo("[email protected]") - .setSubject("Subject Pattern %X{" + subjectKey + "} %maxLen{%m}{10}") - .setSmtpHost(HOST) - .setSmtpPort(smtpPort) - .setBufferSize(3) - .build(); - appender.start(); - - final LoggerContext context = LoggerContext.getContext(); - final Logger root = context.getLogger("SMTPAppenderTest"); - root.addAppender(appender); - root.setAdditive(false); - root.setLevel(Level.DEBUG); - - final SimpleSmtpServer server = SimpleSmtpServer.start(smtpPort); - - root.debug("Debug message #1"); - root.debug("Debug message #2"); - root.debug("Debug message #3"); - root.debug("Debug message #4"); - root.error("Error with exception", new RuntimeException("Exception message")); - root.error("Error message #2"); - - server.stop(); - assertTrue(server.getReceivedEmailSize() == 2); - final Iterator<SmtpMessage> messages = server.getReceivedEmail(); - final SmtpMessage email = messages.next(); - - assertEquals("[email protected]", email.getHeaderValue("To")); - assertEquals("[email protected]", email.getHeaderValue("Cc")); - // assertEquals("[email protected]", email.getHeaderValue("Bcc")); // BCC - // can't be tested with Dumpster 1.6 - assertEquals("[email protected]", email.getHeaderValue("From")); - assertEquals("[email protected]", email.getHeaderValue("Reply-To")); - assertEquals("Subject Pattern " + subjectValue +" Error with", email.getHeaderValue("Subject")); - - final String body = email.getBody(); - assertFalse(body.contains("Debug message #1")); - assertTrue(body.contains("Debug message #2")); - assertTrue(body.contains("Debug message #3")); - assertTrue(body.contains("Debug message #4")); - assertTrue(body.contains("Error with exception")); - assertTrue(body.contains("RuntimeException")); - assertTrue(body.contains("Exception message")); - assertFalse(body.contains("Error message #2")); - - final SmtpMessage email2 = messages.next(); - - assertEquals("Subject Pattern " + subjectValue +" Error mess", email2.getHeaderValue("Subject")); - - final String body2 = email2.getBody(); - assertFalse(body2.contains("Debug message #4")); - assertFalse(body2.contains("Error with exception")); - assertTrue(body2.contains("Error message #2")); - } -} diff --git a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpManagerTest.java b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpManagerTest.java deleted file mode 100644 index 65ceccc1f3..0000000000 --- a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpManagerTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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.apache.logging.log4j.smtp.appender; - -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.async.RingBufferLogEvent; -import org.apache.logging.log4j.core.config.DefaultConfiguration; -import org.apache.logging.log4j.core.impl.Log4jLogEvent; -import org.apache.logging.log4j.core.impl.MementoMessage; -import org.apache.logging.log4j.core.impl.MutableLogEvent; -import org.apache.logging.log4j.core.time.ClockFactory; -import org.apache.logging.log4j.core.time.internal.DummyNanoClock; -import org.apache.logging.log4j.message.ReusableMessage; -import org.apache.logging.log4j.message.ReusableSimpleMessage; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Unit tests for {@link SmtpManager}. - */ -public class SmtpManagerTest { - - @Test - void testCreateManagerName() { - final String managerName = SmtpManager.createManagerName("to", "cc", null, "from", null, "LOG4J2-3107", - "proto", "smtp.log4j.com", 4711, "username", false, "filter"); - assertEquals("SMTP:to:cc::from::LOG4J2-3107:proto:smtp.log4j.com:4711:username::filter", managerName); - } - - private void testAdd(final LogEvent event) { - final SmtpManager smtpManager = SmtpManager.getSmtpManager(new DefaultConfiguration(), "to", "cc", "bcc", "from", "replyTo", "subject", "protocol", "host", 0, "username", "password", false, "filterName", 10, null); - smtpManager.removeAllBufferedEvents(); // in case this smtpManager is reused - smtpManager.add(event); - - final LogEvent[] bufferedEvents = smtpManager.removeAllBufferedEvents(); - assertThat("unexpected number of buffered events", bufferedEvents.length, is(1)); - assertThat("expected the immutable version of the event to be buffered", bufferedEvents[0].getMessage(), is(instanceOf(MementoMessage.class))); - } - - // LOG4J2-3172: make sure existing protections are not violated - @Test - void testAdd_WhereLog4jLogEventWithReusableMessage() { - final LogEvent event = new Log4jLogEvent.Builder().setMessage(getReusableMessage("test message")).build(); - testAdd(event); - } - - // LOG4J2-3172: make sure existing protections are not violated - @Test - void testAdd_WhereMutableLogEvent() { - final MutableLogEvent event = new MutableLogEvent(new StringBuilder("test message"), null); - testAdd(event); - } - - // LOG4J2-3172 - @Test - void testAdd_WhereRingBufferLogEvent() { - final RingBufferLogEvent event = new RingBufferLogEvent(); - event.setValues(null, null, null, null, null, getReusableMessage("test message"), null, null, null, 0, null, 0, null, ClockFactory.getClock(), new DummyNanoClock()); - testAdd(event); - } - - private ReusableMessage getReusableMessage(final String text) { - final ReusableSimpleMessage message = new ReusableSimpleMessage(); - message.set(text); - return message; - } - -} diff --git a/log4j-smtp/src/test/resources/SmtpAppenderAsyncTest.xml b/log4j-smtp/src/test/resources/SmtpAppenderAsyncTest.xml deleted file mode 100644 index ff29f544df..0000000000 --- a/log4j-smtp/src/test/resources/SmtpAppenderAsyncTest.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Licensed to the Apache Software Foundation (ASF) under one or more - ~ contributor license agreements. See the NOTICE file distributed with - ~ this work for additional information regarding copyright ownership. - ~ The ASF licenses this file to you 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. - --> -<Configuration name="SmtpAppenderAsyncTest" status="WARN"> - <Appenders> - <SMTP name="mail-sync" to="[email protected]" from="[email protected]" smtpHost="localhost" - smtpPort="${sys:smtp.port}" ignoreExceptions="false" subject="[%X{MDC1}]"> - <PatternLayout pattern="Body:[%X{MDC1}]" /> - </SMTP> - <Async name="mail-async"> - <AppenderRef ref="mail-sync"/> - </Async> - <Console name="Console" target="SYSTEM_OUT"> - <PatternLayout pattern="%d [%t] %-5level: %msg%n%throwable" /> - </Console> - </Appenders> - <Loggers> - <Root level="FATAL"> - <AppenderRef ref="Console"/> - </Root> - <Logger name="sync" level="INFO"> - <AppenderRef ref="mail-sync"/> - </Logger> - <Logger name="async" level="INFO"> - <AppenderRef ref="mail-async"/> - </Logger> - </Loggers> -</Configuration> diff --git a/pom.xml b/pom.xml index 4737881f96..f1afdd23a5 100644 --- a/pom.xml +++ b/pom.xml @@ -270,7 +270,6 @@ <module>log4j-script</module> <module>log4j-slf4j2-impl</module> <module>log4j-slf4j-impl</module> - <module>log4j-smtp</module> <module>log4j-spring-boot</module> <module>log4j-spring-cloud-config</module> <module>log4j-taglib</module> @@ -570,12 +569,6 @@ <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-smtp</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-spring-boot</artifactId> diff --git a/src/site/asciidoc/runtime-dependencies.adoc b/src/site/asciidoc/runtime-dependencies.adoc index 65361a50ee..003c7b08da 100644 --- a/src/site/asciidoc/runtime-dependencies.adoc +++ b/src/site/asciidoc/runtime-dependencies.adoc @@ -537,9 +537,6 @@ the exact list of JAR files needed for these features. You need to use a version of the Kafka client library matching the Kafka server used. ==== -|SMTP Appender -|an implementation of `javax.mail` - |Windows console color support |http://jansi.fusesource.org/[Jansi]
