Skip to content

Commit e852bdc

Browse files
Merge pull request #10 from dynamiatools/3.x
Upgrade to DynamiaTools 5.4.7 and improved javadocs
2 parents be40303 + 29e7cfc commit e852bdc

9 files changed

Lines changed: 182 additions & 63 deletions

File tree

sources/core/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
<parent>
2323
<artifactId>tools.dynamia.modules.email.parent</artifactId>
2424
<groupId>tools.dynamia.modules</groupId>
25-
<version>3.4.0</version>
25+
<version>3.5.0</version>
2626
</parent>
2727

2828
<artifactId>tools.dynamia.modules.email</artifactId>
2929
<name>DynamiaModules - Email</name>
30-
<version>3.4.0</version>
30+
<version>3.5.0</version>
3131
<url>https://www.dynamiasoluciones.com</url>
3232

3333

sources/core/src/main/java/tools/dynamia/modules/email/SMSServiceListener.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/*
32
* Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
43
* Colombia / South America
@@ -19,15 +18,42 @@
1918
package tools.dynamia.modules.email;
2019

2120
/**
22-
* Implement this class if you need listener sms message sending process. You also need annotated
23-
* with @{@link tools.dynamia.integration.sterotypes.Listener}
21+
* Listener interface for the SMS message sending lifecycle.
22+
* <p>
23+
* Implement this interface to receive callbacks during the SMS dispatch process. To enable discovery
24+
* and registration by the integration framework, annotate your implementation class with
25+
* {@link tools.dynamia.integration.sterotypes.Listener}.
26+
* </p>
27+
* <p>
28+
* Typical implementations may log audit trails, collect metrics, or alter message metadata before
29+
* sending. Note: method names reflect existing API and should not be changed for compatibility.
30+
* </p>
2431
*
2532
* @author Mario Serrano Leones
2633
*/
2734
public interface SMSServiceListener {
2835

36+
/**
37+
* Callback invoked right before an {@link SMSMessage} is sent.
38+
* <p>
39+
* Use this hook to validate, enrich, or log the message prior to delivery. Avoid long-running
40+
* operations to prevent delaying the sending process.
41+
* </p>
42+
*
43+
* @param message The SMS message about to be sent. Never null.
44+
*/
2945
void onMessageSending(SMSMessage message);
3046

47+
/**
48+
* Callback invoked immediately after an {@link SMSMessage} has been sent.
49+
* <p>
50+
* Despite the name "Sended" kept for backward compatibility, this method indicates that the
51+
* sending operation was executed. Implementations may record provider responses or update
52+
* delivery tracking. This does not necessarily guarantee final delivery to the recipient.
53+
* </p>
54+
*
55+
* @param message The SMS message that was processed by the sender. Never null.
56+
*/
3157
void onMessageSended(SMSMessage message);
3258

3359

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/*
32
* Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
43
* Colombia / South America
@@ -18,113 +17,178 @@
1817

1918
package tools.dynamia.modules.email.services;
2019

21-
import org.springframework.transaction.annotation.Transactional;
2220
import tools.dynamia.modules.email.EmailMessage;
2321
import tools.dynamia.modules.email.EmailSendResult;
2422
import tools.dynamia.modules.email.domain.EmailAccount;
2523
import tools.dynamia.modules.email.domain.EmailAddress;
2624
import tools.dynamia.modules.email.domain.EmailTemplate;
2725

28-
import java.util.concurrent.Future;
26+
import java.util.concurrent.CompletableFuture;
2927

3028
/**
31-
* Email service for sending emails
29+
* Email service for sending emails and managing email-related resources.
30+
* <p>
31+
* This service defines the contract to send emails synchronously and asynchronously, resolve
32+
* preferred/notification accounts, manage templates, log addresses, and control internal caches.
33+
* Implementations may rely on Spring's async and scheduling infrastructure.
34+
* </p>
3235
*
3336
* @author Mario Serrano Leones
3437
*/
3538
public interface EmailService {
3639

3740
/**
38-
* Send email message asynchronously. Default implementation use Spring Scheduling and Async API. Make sure your
39-
* application has {@link org.springframework.scheduling.annotation.EnableAsync} and
40-
* {@link org.springframework.scheduling.annotation.EnableScheduling} configured.
41+
* Sends an email message asynchronously.
42+
* <p>
43+
* Default implementations are expected to use Spring's {@code @EnableAsync} and scheduling facilities.
44+
* Ensure your application has {@link org.springframework.scheduling.annotation.EnableAsync} and
45+
* {@link org.springframework.scheduling.annotation.EnableScheduling} enabled so the task executor handles
46+
* background execution properly.
47+
* </p>
4148
*
42-
* @param message
49+
* @param message Fully built {@link EmailMessage} to be sent, including recipients, subject, content,
50+
* attachments, and any headers.
51+
* @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} indicating success or failure.
52+
* The future is completed exceptionally if an unrecoverable error occurs during dispatch.
4353
*/
44-
Future<EmailSendResult> send(EmailMessage message);
54+
CompletableFuture<EmailSendResult> send(EmailMessage message);
4555

4656
/**
47-
* Build and send email message asynchronously. See {@link EmailService#send(EmailMessage)}
57+
* Builds and sends an email message asynchronously based on simple inputs.
58+
* <p>
59+
* This is a convenience method that internally creates an {@link EmailMessage} with a single recipient,
60+
* subject, and content, and then delegates to {@link #send(EmailMessage)}.
61+
* </p>
4862
*
49-
* @param to
50-
* @param subject
51-
* @param content
63+
* @param to Recipient email address (e.g., "user@example.com"). Must be a valid RFC 5322 address.
64+
* @param subject Email subject line.
65+
* @param content Email body content. Implementations may treat this as plain text or HTML depending on configuration.
66+
* @return a {@link CompletableFuture} that completes with an {@link EmailSendResult} when sending finishes.
5267
*/
53-
Future<EmailSendResult> send(String to, String subject, String content);
68+
CompletableFuture<EmailSendResult> send(String to, String subject, String content);
5469

70+
/**
71+
* Returns the default notification {@link EmailAccount} to be used for system-generated emails
72+
* in the current SaaS context.
73+
*
74+
* @return the configured notification email account, or {@code null} if none is configured.
75+
*/
5576
EmailAccount getNotificationEmailAccount();
5677

78+
/**
79+
* Returns the notification {@link EmailAccount} associated with the given SaaS account id.
80+
*
81+
* @param accountId SaaS account identifier.
82+
* @return the notification email account for the provided {@code accountId}, or {@code null} if not found.
83+
*/
5784
EmailAccount getNotificationEmailAccount(Long accountId);
5885

5986
/**
60-
* Setup preferred email account in current SaaS account
87+
* Sets the preferred {@link EmailAccount} for the current SaaS account.
88+
* Implementations should persist this preference so subsequent calls to
89+
* {@link #getPreferredEmailAccount()} return this account.
6190
*
62-
* @param account
91+
* @param account The {@link EmailAccount} to set as preferred. Must be a valid, enabled account.
6392
*/
6493
void setPreferredEmailAccount(EmailAccount account);
6594

95+
/**
96+
* Sends an email message synchronously and waits for the result.
97+
* <p>
98+
* Use this method when you need immediate feedback about delivery status. Consider timeouts and
99+
* potential blocking behavior in your calling thread.
100+
* </p>
101+
*
102+
* @param mailMessage Fully built {@link EmailMessage} to be sent.
103+
* @return the {@link EmailSendResult} containing delivery details, success flag, and error information if any.
104+
*/
66105
EmailSendResult sendAndWait(EmailMessage mailMessage);
67106

68107
/**
69-
* Get preferred email account in current SaaS account
108+
* Returns the preferred {@link EmailAccount} for the current SaaS account.
70109
*
71-
* @return
110+
* @return the preferred account, or {@code null} if none has been configured.
72111
*/
73112
EmailAccount getPreferredEmailAccount();
74113

75114
/**
76-
* Get preferred email account in SaaS account ID
115+
* Returns the preferred {@link EmailAccount} for the specified SaaS account id.
77116
*
78-
* @return
117+
* @param accountId SaaS account identifier.
118+
* @return the preferred email account for {@code accountId}, or {@code null} if not configured.
79119
*/
80120
EmailAccount getPreferredEmailAccount(Long accountId);
81121

82122
/**
83-
* Find email template by name in current SaaS account. If autocreate is true a new blank email template is created
123+
* Finds an {@link EmailTemplate} by name within the current SaaS account.
124+
* If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created
125+
* and returned.
84126
*
85-
* @param name
86-
* @param autocreate
87-
* @return
127+
* @param name Template name to search for.
128+
* @param autocreate Whether to create a new template if one is not found.
129+
* @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate}
130+
* is {@code false}.
88131
*/
89132
EmailTemplate getTemplateByName(String name, boolean autocreate);
90133

134+
/**
135+
* Finds an {@link EmailTemplate} by name for a specific SaaS account id.
136+
* If {@code autocreate} is {@code true} and the template does not exist, a new blank template will be created
137+
* under that account.
138+
*
139+
* @param name Template name to search for.
140+
* @param autocreate Whether to create a new template if one is not found.
141+
* @param accountId SaaS account identifier.
142+
* @return the existing or newly created {@link EmailTemplate}, or {@code null} if not found and {@code autocreate}
143+
* is {@code false}.
144+
*/
91145
EmailTemplate getTemplateByName(String name, boolean autocreate, Long accountId);
92146

93147
/**
94-
* Find email template by name
148+
* Finds an {@link EmailTemplate} by name using default lookup rules for the current SaaS account.
95149
*
96-
* @param name
97-
* @return
150+
* @param name Template name to search for.
151+
* @return the matching {@link EmailTemplate}, or {@code null} if none exists.
98152
*/
99153
EmailTemplate getTemplateByName(String name);
100154

101155
/**
102-
* Log all email address from message
156+
* Logs all email addresses present in the given {@link EmailMessage}.
157+
* <p>
158+
* Implementations should inspect TO, CC, BCC, REPLY-TO (and possibly FROM) fields and persist or update
159+
* a registry of known {@link EmailAddress} entries associated with the supplied {@link EmailAccount}.
160+
* </p>
103161
*
104-
* @param message
162+
* @param account The {@link EmailAccount} context in which addresses will be logged.
163+
* @param message The {@link EmailMessage} whose addresses should be extracted and logged.
105164
*/
106165
void logEmailAddress(EmailAccount account, EmailMessage message);
107166

108167
/**
109-
* Log email address
168+
* Logs a single email address with an optional tag for classification.
110169
*
111-
* @param address
112-
* @param tag
170+
* @param account The {@link EmailAccount} context used to associate the address entry.
171+
* @param address A valid email address string to log.
172+
* @param tag A marker or label (e.g., "customer", "supplier", "notification") to categorize the address.
113173
*/
114174
void logEmailAddress(EmailAccount account, String address, String tag);
115175

116176
/**
117-
* Find a logged email address
177+
* Retrieves a previously logged {@link EmailAddress} by its string representation.
118178
*
119-
* @param address
120-
* @return
179+
* @param address Email address string to look up.
180+
* @return the {@link EmailAddress} entity if found; otherwise {@code null}.
121181
*/
122182
EmailAddress getEmailAddress(String address);
123183

124184
/**
125-
* Clears the mail sender cache for the specified email account.
185+
* Clears the internal mail-sender cache for the specified {@link EmailAccount}.
186+
* <p>
187+
* Implementations that cache mail sender instances (e.g., JavaMailSender) should discard and recreate them
188+
* after configuration changes like credentials, host, or port updates.
189+
* </p>
126190
*
127-
* @param account The email account for which to clear the cache.
191+
* @param account The email account whose cache entries should be invalidated. Must not be {@code null}.
128192
*/
129193
void clearCache(EmailAccount account);
130194
}

sources/core/src/main/java/tools/dynamia/modules/email/services/OTPService.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,35 @@
33
import tools.dynamia.modules.email.OTPMessage;
44
import tools.dynamia.modules.email.OTPSendResult;
55

6+
import java.util.concurrent.CompletableFuture;
67
import java.util.concurrent.Future;
78

9+
/**
10+
* Service interface to dispatch One-Time Password (OTP) messages.
11+
* <p>
12+
* Implementations may deliver OTP codes via email, SMS, or both, depending on configuration and
13+
* the contents of the provided {@link OTPMessage}. The service abstracts transport selection,
14+
* formatting, and delivery tracking, returning an asynchronous handle to inspect the result.
15+
* </p>
16+
* <p>
17+
* Typical usage: build an {@link OTPMessage} with target channels and the OTP value, then call {@link #send(OTPMessage)}.
18+
* </p>
19+
*/
820
public interface OTPService {
921

10-
1122
/**
12-
* Send OTP message using email, sms or both service
23+
* Sends an OTP message using email, SMS, or both channels.
24+
* <p>
25+
* The selected transport(s) depend on implementation and the {@link OTPMessage} fields (e.g., presence of
26+
* email address, phone number, or explicit channel selection). Delivery may happen asynchronously; use the
27+
* returned {@link Future} to check completion and obtain the {@link OTPSendResult}.
28+
* </p>
1329
*
14-
* @param message
15-
* @return
30+
* @param message Fully populated {@link OTPMessage} containing the OTP code, target recipient(s), preferred
31+
* channel(s), expiration and metadata as required by the implementation. Must not be null.
32+
* @return a {@link Future} that completes with {@link OTPSendResult} indicating success, failure, and relevant
33+
* details (e.g., which channels were used). The future may complete exceptionally if an unrecoverable error occurs.
1634
*/
17-
Future<OTPSendResult> send(OTPMessage message);
35+
CompletableFuture<OTPSendResult> send(OTPMessage message);
1836

1937
}

sources/core/src/main/java/tools/dynamia/modules/email/services/SMSService.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,27 @@
2020
import tools.dynamia.modules.email.SMSMessage;
2121

2222
/**
23-
* Simple SMS sender service
23+
* Simple SMS sender service.
24+
* <p>
25+
* Defines the contract to dispatch SMS messages using the configured provider. Implementations
26+
* are responsible for formatting, transport selection, and returning a provider-specific response
27+
* string that may include tracking identifiers or delivery status notes.
28+
* </p>
2429
*/
2530
public interface SMSService {
2631

2732
/**
2833
* Sends an SMS message.
34+
* <p>
35+
* Implementations should validate destination numbers and message length according to provider limits
36+
* (e.g., GSM-7 vs. Unicode, segmentation). The returned value is the raw response from the underlying
37+
* SMS provider and can be used for logging or troubleshooting.
38+
* </p>
2939
*
30-
* @param message the SMS message to be sent
31-
* @return the response from the SMS service
40+
* @param message The {@link SMSMessage} to be sent, containing destination number, text content, and optional metadata.
41+
* Must not be {@code null}.
42+
* @return The response string from the SMS service/provider. The format depends on the implementation and provider;
43+
* may include message ID or delivery status information.
3244
*/
3345
String send(SMSMessage message);
3446
}

sources/core/src/main/java/tools/dynamia/modules/email/services/impl/EmailServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ public EmailServiceImpl(TemplateEngine templateEngine, CrudService crudService,
8888
private final LoggingService logger = new SLF4JLoggingService(EmailService.class);
8989

9090
@Override
91-
public Future<EmailSendResult> send(String to, String subject, String content) {
91+
public CompletableFuture<EmailSendResult> send(String to, String subject, String content) {
9292
return send(new EmailMessage(to, subject, content));
9393
}
9494

95-
public Future<EmailSendResult> send(final EmailMessage mailMessage) {
95+
public CompletableFuture<EmailSendResult> send(final EmailMessage mailMessage) {
9696
try {
9797

9898
loadEmailAccount(mailMessage);

sources/core/src/main/java/tools/dynamia/modules/email/services/impl/OTPServiceImpl.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package tools.dynamia.modules.email.services.impl;
22

33
import tools.dynamia.integration.scheduling.SchedulerUtil;
4-
import tools.dynamia.integration.scheduling.TaskWithResult;
54
import tools.dynamia.integration.sterotypes.Service;
65
import tools.dynamia.modules.email.EmailMessage;
76
import tools.dynamia.modules.email.OTPMessage;
@@ -12,7 +11,7 @@
1211
import tools.dynamia.modules.email.services.OTPService;
1312
import tools.dynamia.modules.email.services.SMSService;
1413

15-
import java.util.concurrent.Future;
14+
import java.util.concurrent.CompletableFuture;
1615

1716
@Service
1817
public class OTPServiceImpl implements OTPService {
@@ -26,7 +25,7 @@ public OTPServiceImpl(EmailService emailService, SMSService smsService) {
2625
}
2726

2827
@Override
29-
public Future<OTPSendResult> send(OTPMessage message) {
28+
public CompletableFuture<OTPSendResult> send(OTPMessage message) {
3029
final var emailAccount = message.getAccountId() != null ? emailService.getPreferredEmailAccount(message.getAccountId()) : emailService.getPreferredEmailAccount();
3130
final var emailMessage = buildEmailMessage(emailAccount, message);
3231
final var smsMessage = buildSMSMessage(emailAccount, message);

0 commit comments

Comments
 (0)