diff --git a/sources/core/pom.xml b/sources/core/pom.xml index cafd86c..6893e4e 100644 --- a/sources/core/pom.xml +++ b/sources/core/pom.xml @@ -22,12 +22,12 @@ tools.dynamia.modules.email.parent tools.dynamia.modules - 3.4.0 + 3.5.0 tools.dynamia.modules.email DynamiaModules - Email - 3.4.0 + 3.5.0 https://www.dynamiasoluciones.com diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/SMSServiceListener.java b/sources/core/src/main/java/tools/dynamia/modules/email/SMSServiceListener.java index bd456b9..8a6f613 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/SMSServiceListener.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/SMSServiceListener.java @@ -1,4 +1,3 @@ - /* * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 * Colombia / South America @@ -19,15 +18,42 @@ package tools.dynamia.modules.email; /** - * Implement this class if you need listener sms message sending process. You also need annotated - * with @{@link tools.dynamia.integration.sterotypes.Listener} + * Listener interface for the SMS message sending lifecycle. + *

+ * Implement this interface to receive callbacks during the SMS dispatch process. To enable discovery + * and registration by the integration framework, annotate your implementation class with + * {@link tools.dynamia.integration.sterotypes.Listener}. + *

+ *

+ * Typical implementations may log audit trails, collect metrics, or alter message metadata before + * sending. Note: method names reflect existing API and should not be changed for compatibility. + *

* * @author Mario Serrano Leones */ public interface SMSServiceListener { + /** + * Callback invoked right before an {@link SMSMessage} is sent. + *

+ * Use this hook to validate, enrich, or log the message prior to delivery. Avoid long-running + * operations to prevent delaying the sending process. + *

+ * + * @param message The SMS message about to be sent. Never null. + */ void onMessageSending(SMSMessage message); + /** + * Callback invoked immediately after an {@link SMSMessage} has been sent. + *

+ * Despite the name "Sended" kept for backward compatibility, this method indicates that the + * sending operation was executed. Implementations may record provider responses or update + * delivery tracking. This does not necessarily guarantee final delivery to the recipient. + *

+ * + * @param message The SMS message that was processed by the sender. Never null. + */ void onMessageSended(SMSMessage message); diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java index 5de5fde..6104e9a 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/EmailService.java @@ -1,4 +1,3 @@ - /* * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 * Colombia / South America @@ -18,113 +17,178 @@ package tools.dynamia.modules.email.services; -import org.springframework.transaction.annotation.Transactional; import tools.dynamia.modules.email.EmailMessage; import tools.dynamia.modules.email.EmailSendResult; import tools.dynamia.modules.email.domain.EmailAccount; import tools.dynamia.modules.email.domain.EmailAddress; import tools.dynamia.modules.email.domain.EmailTemplate; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; /** - * Email service for sending emails + * Email service for sending emails and managing email-related resources. + *

+ * This service defines the contract to send emails synchronously and asynchronously, resolve + * preferred/notification accounts, manage templates, log addresses, and control internal caches. + * Implementations may rely on Spring's async and scheduling infrastructure. + *

* * @author Mario Serrano Leones */ public interface EmailService { /** - * Send email message asynchronously. Default implementation use Spring Scheduling and Async API. Make sure your - * application has {@link org.springframework.scheduling.annotation.EnableAsync} and - * {@link org.springframework.scheduling.annotation.EnableScheduling} configured. + * Sends an email message asynchronously. + *

+ * Default implementations are expected to use Spring's {@code @EnableAsync} and scheduling facilities. + * Ensure your application has {@link org.springframework.scheduling.annotation.EnableAsync} and + * {@link org.springframework.scheduling.annotation.EnableScheduling} enabled so the task executor handles + * background execution properly. + *

* - * @param message + * @param message Fully built {@link EmailMessage} to be sent, including recipients, subject, content, + * attachments, and any headers. + * @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} indicating success or failure. + * The future is completed exceptionally if an unrecoverable error occurs during dispatch. */ - Future send(EmailMessage message); + CompletableFuture send(EmailMessage message); /** - * Build and send email message asynchronously. See {@link EmailService#send(EmailMessage)} + * Builds and sends an email message asynchronously based on simple inputs. + *

+ * This is a convenience method that internally creates an {@link EmailMessage} with a single recipient, + * subject, and content, and then delegates to {@link #send(EmailMessage)}. + *

* - * @param to - * @param subject - * @param content + * @param to Recipient email address (e.g., "user@example.com"). Must be a valid RFC 5322 address. + * @param subject Email subject line. + * @param content Email body content. Implementations may treat this as plain text or HTML depending on configuration. + * @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} when sending finishes. */ - Future send(String to, String subject, String content); + CompletableFuture send(String to, String subject, String content); + /** + * Returns the default notification {@link EmailAccount} to be used for system-generated emails + * in the current SaaS context. + * + * @return the configured notification email account, or {@code null} if none is configured. + */ EmailAccount getNotificationEmailAccount(); + /** + * Returns the notification {@link EmailAccount} associated with the given SaaS account id. + * + * @param accountId SaaS account identifier. + * @return the notification email account for the provided {@code accountId}, or {@code null} if not found. + */ EmailAccount getNotificationEmailAccount(Long accountId); /** - * Setup preferred email account in current SaaS account + * Sets the preferred {@link EmailAccount} for the current SaaS account. + * Implementations should persist this preference so subsequent calls to + * {@link #getPreferredEmailAccount()} return this account. * - * @param account + * @param account The {@link EmailAccount} to set as preferred. Must be a valid, enabled account. */ void setPreferredEmailAccount(EmailAccount account); + /** + * Sends an email message synchronously and waits for the result. + *

+ * Use this method when you need immediate feedback about delivery status. Consider timeouts and + * potential blocking behavior in your calling thread. + *

+ * + * @param mailMessage Fully built {@link EmailMessage} to be sent. + * @return the {@link EmailSendResult} containing delivery details, success flag, and error information if any. + */ EmailSendResult sendAndWait(EmailMessage mailMessage); /** - * Get preferred email account in current SaaS account + * Returns the preferred {@link EmailAccount} for the current SaaS account. * - * @return + * @return the preferred account, or {@code null} if none has been configured. */ EmailAccount getPreferredEmailAccount(); /** - * Get preferred email account in SaaS account ID + * Returns the preferred {@link EmailAccount} for the specified SaaS account id. * - * @return + * @param accountId SaaS account identifier. + * @return the preferred email account for {@code accountId}, or {@code null} if not configured. */ EmailAccount getPreferredEmailAccount(Long accountId); /** - * Find email template by name in current SaaS account. If autocreate is true a new blank email template is created + * Finds an {@link EmailTemplate} by name within the current SaaS account. + * If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created + * and returned. * - * @param name - * @param autocreate - * @return + * @param name Template name to search for. + * @param autocreate Whether to create a new template if one is not found. + * @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate} + * is {@code false}. */ EmailTemplate getTemplateByName(String name, boolean autocreate); + /** + * Finds an {@link EmailTemplate} by name for a specific SaaS account id. + * If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created + * under that account. + * + * @param name Template name to search for. + * @param autocreate Whether to create a new template if one is not found. + * @param accountId SaaS account identifier. + * @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate} + * is {@code false}. + */ EmailTemplate getTemplateByName(String name, boolean autocreate, Long accountId); /** - * Find email template by name + * Finds an {@link EmailTemplate} by name using default lookup rules for the current SaaS account. * - * @param name - * @return + * @param name Template name to search for. + * @return the matching {@link EmailTemplate}, or {@code null} if none exists. */ EmailTemplate getTemplateByName(String name); /** - * Log all email address from message + * Logs all email addresses present in the given {@link EmailMessage}. + *

+ * Implementations should inspect TO, CC, BCC, REPLY-TO (and possibly FROM) fields and persist or update + * a registry of known {@link EmailAddress} entries associated with the supplied {@link EmailAccount}. + *

* - * @param message + * @param account The {@link EmailAccount} context in which addresses will be logged. + * @param message The {@link EmailMessage} whose addresses should be extracted and logged. */ void logEmailAddress(EmailAccount account, EmailMessage message); /** - * Log email address + * Logs a single email address with an optional tag for classification. * - * @param address - * @param tag + * @param account The {@link EmailAccount} context used to associate the address entry. + * @param address A valid email address string to log. + * @param tag A marker or label (e.g., "customer", "supplier", "notification") to categorize the address. */ void logEmailAddress(EmailAccount account, String address, String tag); /** - * Find a logged email address + * Retrieves a previously logged {@link EmailAddress} by its string representation. * - * @param address - * @return + * @param address Email address string to look up. + * @return the {@link EmailAddress} entity if found; otherwise {@code null}. */ EmailAddress getEmailAddress(String address); /** - * Clears the mail sender cache for the specified email account. + * Clears the internal mail-sender cache for the specified {@link EmailAccount}. + *

+ * Implementations that cache mail sender instances (e.g., JavaMailSender) should discard and recreate them + * after configuration changes like credentials, host, or port updates. + *

* - * @param account The email account for which to clear the cache. + * @param account The email account whose cache entries should be invalidated. Must not be {@code null}. */ void clearCache(EmailAccount account); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java index cd02105..066d8b5 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java @@ -3,17 +3,35 @@ import tools.dynamia.modules.email.OTPMessage; import tools.dynamia.modules.email.OTPSendResult; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +/** + * Service interface to dispatch One-Time Password (OTP) messages. + *

+ * Implementations may deliver OTP codes via email, SMS, or both, depending on configuration and + * the contents of the provided {@link OTPMessage}. The service abstracts transport selection, + * formatting, and delivery tracking, returning an asynchronous handle to inspect the result. + *

+ *

+ * Typical usage: build an {@link OTPMessage} with target channels and the OTP value, then call {@link #send(OTPMessage)}. + *

+ */ public interface OTPService { - /** - * Send OTP message using email, sms or both service + * Sends an OTP message using email, SMS, or both channels. + *

+ * The selected transport(s) depend on implementation and the {@link OTPMessage} fields (e.g., presence of + * email address, phone number, or explicit channel selection). Delivery may happen asynchronously; use the + * returned {@link Future} to check completion and obtain the {@link OTPSendResult}. + *

* - * @param message - * @return + * @param message Fully populated {@link OTPMessage} containing the OTP code, target recipient(s), preferred + * channel(s), expiration and metadata as required by the implementation. Must not be null. + * @return a {@link Future} that completes with {@link OTPSendResult} indicating success, failure, and relevant + * details (e.g., which channels were used). The future may complete exceptionally if an unrecoverable error occurs. */ - Future send(OTPMessage message); + CompletableFuture send(OTPMessage message); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/SMSService.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/SMSService.java index 177314b..74e1f8e 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/SMSService.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/SMSService.java @@ -20,15 +20,27 @@ import tools.dynamia.modules.email.SMSMessage; /** - * Simple SMS sender service + * Simple SMS sender service. + *

+ * Defines the contract to dispatch SMS messages using the configured provider. Implementations + * are responsible for formatting, transport selection, and returning a provider-specific response + * string that may include tracking identifiers or delivery status notes. + *

*/ public interface SMSService { /** * Sends an SMS message. + *

+ * Implementations should validate destination numbers and message length according to provider limits + * (e.g., GSM-7 vs. Unicode, segmentation). The returned value is the raw response from the underlying + * SMS provider and can be used for logging or troubleshooting. + *

* - * @param message the SMS message to be sent - * @return the response from the SMS service + * @param message The {@link SMSMessage} to be sent, containing destination number, text content, and optional metadata. + * Must not be {@code null}. + * @return The response string from the SMS service/provider. The format depends on the implementation and provider; + * may include message ID or delivery status information. */ String send(SMSMessage message); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java index ddeaa11..865f2d1 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java @@ -88,11 +88,11 @@ public EmailServiceImpl(TemplateEngine templateEngine, CrudService crudService, private final LoggingService logger = new SLF4JLoggingService(EmailService.class); @Override - public Future send(String to, String subject, String content) { + public CompletableFuture send(String to, String subject, String content) { return send(new EmailMessage(to, subject, content)); } - public Future send(final EmailMessage mailMessage) { + public CompletableFuture send(final EmailMessage mailMessage) { try { loadEmailAccount(mailMessage); diff --git a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/OTPServiceImpl.java b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/OTPServiceImpl.java index 491a104..13048e1 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/OTPServiceImpl.java +++ b/sources/core/src/main/java/tools/dynamia/modules/email/services/impl/OTPServiceImpl.java @@ -1,7 +1,6 @@ package tools.dynamia.modules.email.services.impl; import tools.dynamia.integration.scheduling.SchedulerUtil; -import tools.dynamia.integration.scheduling.TaskWithResult; import tools.dynamia.integration.sterotypes.Service; import tools.dynamia.modules.email.EmailMessage; import tools.dynamia.modules.email.OTPMessage; @@ -12,7 +11,7 @@ import tools.dynamia.modules.email.services.OTPService; import tools.dynamia.modules.email.services.SMSService; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; @Service public class OTPServiceImpl implements OTPService { @@ -26,7 +25,7 @@ public OTPServiceImpl(EmailService emailService, SMSService smsService) { } @Override - public Future send(OTPMessage message) { + public CompletableFuture send(OTPMessage message) { final var emailAccount = message.getAccountId() != null ? emailService.getPreferredEmailAccount(message.getAccountId()) : emailService.getPreferredEmailAccount(); final var emailMessage = buildEmailMessage(emailAccount, message); final var smsMessage = buildSMSMessage(emailAccount, message); diff --git a/sources/pom.xml b/sources/pom.xml index 2f48b8c..79b3ce8 100644 --- a/sources/pom.xml +++ b/sources/pom.xml @@ -23,7 +23,7 @@ tools.dynamia.modules.email.parent DynamiaModules - Email Parent pom - 3.4.0 + 3.5.0 DynamiaTools extension for sending async emails (SMTP) and sms messages (AWS SNS) 2018 https://www.dynamia.tools/modules/email @@ -56,12 +56,12 @@ 21 - 5.4.0 - 3.4.0 + 5.4.7 + 3.5.0 3.14.0 UTF-8 - 3.5.3 - 2.31.61 + 3.5.8 + 2.39.5 diff --git a/sources/ui/pom.xml b/sources/ui/pom.xml index f6cc847..c194d14 100644 --- a/sources/ui/pom.xml +++ b/sources/ui/pom.xml @@ -20,12 +20,12 @@ tools.dynamia.modules.email.parent tools.dynamia.modules - 3.4.0 + 3.5.0 4.0.0 DynamiaModules - Email UI tools.dynamia.modules.email.ui - 3.4.0 + 3.5.0 https://www.dynamiasoluciones.com @@ -38,7 +38,7 @@ tools.dynamia.modules tools.dynamia.modules.email - 3.4.0 + 3.5.0 tools.dynamia.zk.addons