All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simplejavamail.mailer.internal.util.TransportRunner Maven / Gradle / Ivy

There is a newer version: 8.12.4
Show newest version
/*
 * Copyright © 2009 Benny Bottema ([email protected])
 *
 * 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.simplejavamail.mailer.internal.util;

import jakarta.mail.MessagingException;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import lombok.val;
import org.jetbrains.annotations.NotNull;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.internal.batchsupport.LifecycleDelegatingTransport;
import org.simplejavamail.internal.moduleloader.ModuleLoader;
import org.simplejavamail.internal.modules.BatchModule;
import org.simplejavamail.internal.util.MiscUtil;
import org.simplejavamail.mailer.internal.SessionBasedEmailToMimeMessageConverter;
import org.slf4j.Logger;

import java.util.UUID;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * If available, runs activities on Transport connections using SMTP connection pool from the batch-module.
 * 

* Otherwise, always creates a new connection to run the activity on. *

* Note that * multiple threads can safely use a Session, but are synchronized in the Transport connection. */ public class TransportRunner { private static final Logger LOGGER = getLogger(TransportRunner.class); /** * NOTE: only in case batch-module is *not* in use, the {@link Session} passed in here is guaranteed to be used to send this message. * * @param clusterKey The cluster key to use for the connection pool, which was randomly generated in the Mailer builder if not provided. */ public static void sendMessage(@NotNull final UUID clusterKey, final Session session, @NotNull Email email) throws MessagingException { runOnSessionTransport(clusterKey, session, false, (transport, actualSessionUsed) -> { val message = SessionBasedEmailToMimeMessageConverter.convertAndLogMimeMessage(actualSessionUsed, email); val actualRecipients = email.getOverrideReceivers().isEmpty() ? message.getAllRecipients() : MiscUtil.asInternetAddresses(email.getOverrideReceivers(), UTF_8).toArray(new InternetAddress[0]); transport.sendMessage(message, actualRecipients); LOGGER.trace("...email sent"); }); } public static void connect(@NotNull UUID clusterKey, final Session session) throws MessagingException { runOnSessionTransport(clusterKey, session, true, (transport, actualSessionUsed) -> { // the fact that we reached here means a connection was made successfully LOGGER.debug("...connection successful"); }); } private static void runOnSessionTransport(@NotNull UUID clusterKey, Session session, final boolean stickySession, TransportRunnable runnable) throws MessagingException { if (ModuleLoader.batchModuleAvailable()) { sendUsingConnectionPool(ModuleLoader.loadBatchModule(), clusterKey, session, stickySession, runnable); } else { try (Transport transport = session.getTransport()) { TransportConnectionHelper.connectTransport(transport, session); runnable.run(transport, session); } finally { LOGGER.trace("closing transport"); } } } private static void sendUsingConnectionPool(@NotNull BatchModule batchModule, @NotNull UUID clusterKey, Session session, boolean stickySession, TransportRunnable runnable) throws MessagingException { LifecycleDelegatingTransport delegatingTransport = batchModule.acquireTransport(clusterKey, session, stickySession); try { runnable.run(delegatingTransport.getTransport(), delegatingTransport.getSessionUsedToObtainTransport()); } catch (final Throwable t) { // always make sure claimed resources are released delegatingTransport.signalTransportFailed(); throw t; } delegatingTransport.signalTransportUsed(); } private interface TransportRunnable { void run(Transport transport, Session actualSessionUsed) throws MessagingException; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy