Skip to content

Commit 4c9d760

Browse files
authored
Introduce MailClientProvider for dynamic mail client generation (#4187)
1 parent e15ef09 commit 4c9d760

File tree

13 files changed

+626
-88
lines changed

13 files changed

+626
-88
lines changed

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,9 @@
296296
import org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnableFactory;
297297
import org.flowable.job.service.impl.asyncexecutor.FailedJobCommandFactory;
298298
import org.flowable.job.service.impl.asyncexecutor.JobManager;
299+
import org.flowable.common.engine.impl.cfg.mail.DefaultMailClientProvider;
299300
import org.flowable.mail.common.api.client.FlowableMailClient;
301+
import org.flowable.mail.common.api.client.MailClientProvider;
300302
import org.flowable.task.service.InternalTaskAssignmentManager;
301303
import org.flowable.task.service.InternalTaskVariableScopeResolver;
302304
import org.flowable.task.service.TaskPostProcessor;
@@ -526,11 +528,10 @@ public class CmmnEngineConfiguration extends AbstractBuildableEngineConfiguratio
526528
protected HttpClientConfig httpClientConfig = new HttpClientConfig();
527529

528530
// Email
529-
protected FlowableMailClient defaultMailClient;
531+
protected MailClientProvider mailClientProvider = new DefaultMailClientProvider();
530532
protected MailServerInfo defaultMailServer;
531533
protected String mailSessionJndi;
532534
protected Map<String, MailServerInfo> mailServers = new HashMap<>();
533-
protected Map<String, FlowableMailClient> mailClients = new HashMap<>();
534535
protected Map<String, String> mailSessionsJndi = new HashMap<>();
535536

536537
// Async executor
@@ -929,24 +930,31 @@ public void initExpressionManager() {
929930
}
930931

931932
public void initMailClients() {
932-
if (defaultMailClient == null) {
933+
if (mailClientProvider == null) {
934+
mailClientProvider = new DefaultMailClientProvider();
935+
}
936+
if (!(mailClientProvider instanceof DefaultMailClientProvider defaultMailClientProvider)) {
937+
return; // custom provider handles resolution at runtime
938+
}
939+
if (defaultMailClientProvider.getDefaultMailClient() == null) {
933940
String sessionJndi = getMailSessionJndi();
934941
if (sessionJndi != null) {
935-
defaultMailClient = FlowableMailClientCreator.createSessionClient(sessionJndi, getDefaultMailServer());
942+
defaultMailClientProvider.setDefaultMailClient(FlowableMailClientCreator.createSessionClient(sessionJndi, getDefaultMailServer()));
936943
} else {
937944
MailServerInfo mailServer = getDefaultMailServer();
938945
String host = mailServer.getMailServerHost();
939946
if (host == null) {
940947
throw new FlowableException("no SMTP host is configured for the default mail server");
941948
}
942-
defaultMailClient = FlowableMailClientCreator.createHostClient(host, mailServer);
949+
defaultMailClientProvider.setDefaultMailClient(FlowableMailClientCreator.createHostClient(host, mailServer));
943950
}
944951
}
945952

946953
Collection<String> tenantIds = new HashSet<>(mailSessionsJndi.keySet());
947954
tenantIds.addAll(mailServers.keySet());
948955

949956
if (!tenantIds.isEmpty()) {
957+
Map<String, FlowableMailClient> mailClients = defaultMailClientProvider.getMailClients();
950958
MailServerInfo defaultMailServer = getDefaultMailServer();
951959
for (String tenantId : tenantIds) {
952960
if (mailClients.containsKey(tenantId)) {
@@ -4078,12 +4086,34 @@ public CmmnEngineConfiguration setHttpClientConfig(HttpClientConfig httpClientCo
40784086
return this;
40794087
}
40804088

4089+
public MailClientProvider getMailClientProvider() {
4090+
return mailClientProvider;
4091+
}
4092+
4093+
public CmmnEngineConfiguration setMailClientProvider(MailClientProvider mailClientProvider) {
4094+
this.mailClientProvider = mailClientProvider;
4095+
return this;
4096+
}
4097+
4098+
/**
4099+
* @deprecated use {@link #getMailClientProvider()} and {@link MailClientProvider#getMailClient(String)} with tenantId {@code null} instead
4100+
*/
4101+
@Deprecated
40814102
public FlowableMailClient getDefaultMailClient() {
4082-
return defaultMailClient;
4103+
return mailClientProvider.getMailClient(null);
40834104
}
40844105

4106+
/**
4107+
* @deprecated use {@link #setMailClientProvider(MailClientProvider)} instead
4108+
*/
4109+
@Deprecated
40854110
public CmmnEngineConfiguration setDefaultMailClient(FlowableMailClient defaultMailClient) {
4086-
this.defaultMailClient = defaultMailClient;
4111+
if (mailClientProvider instanceof DefaultMailClientProvider defaultProvider) {
4112+
defaultProvider.setDefaultMailClient(defaultMailClient);
4113+
} else {
4114+
throw new FlowableException("The mail client provider is not an instance of DefaultMailClientProvider. "
4115+
+ "Use setMailClientProvider instead.");
4116+
}
40874117
return this;
40884118
}
40894119

@@ -4219,17 +4249,37 @@ public MailServerInfo getMailServer(String tenantId) {
42194249
return mailServers.get(tenantId);
42204250
}
42214251

4252+
/**
4253+
* @deprecated use {@link #getMailClientProvider()} instead
4254+
*/
4255+
@Deprecated
42224256
public Map<String, FlowableMailClient> getMailClients() {
4223-
return mailClients;
4257+
if (mailClientProvider instanceof DefaultMailClientProvider defaultProvider) {
4258+
return defaultProvider.getMailClients();
4259+
}
4260+
return Collections.emptyMap();
42244261
}
42254262

4263+
/**
4264+
* @deprecated use {@link #setMailClientProvider(MailClientProvider)} instead
4265+
*/
4266+
@Deprecated
42264267
public CmmnEngineConfiguration setMailClients(Map<String, FlowableMailClient> mailClients) {
4227-
this.mailClients = mailClients;
4268+
if (this.mailClientProvider instanceof DefaultMailClientProvider defaultProvider) {
4269+
defaultProvider.getMailClients().putAll(mailClients);
4270+
} else {
4271+
throw new FlowableException("The mail client provider is not an instance of DefaultMailClientProvider. "
4272+
+ "Use setMailClientProvider instead.");
4273+
}
42284274
return this;
42294275
}
42304276

4277+
/**
4278+
* @deprecated use {@link #getMailClientProvider().getMailClient(String)} instead
4279+
*/
4280+
@Deprecated
42314281
public FlowableMailClient getMailClient(String tenantId) {
4232-
return mailClients.get(tenantId);
4282+
return mailClientProvider.getMailClient(tenantId);
42334283
}
42344284

42354285
public Map<String, String> getMailSessionsJndi() {

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/mail/CmmnMailActivityDelegate.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
*/
1313
package org.flowable.cmmn.engine.impl.behavior.impl.mail;
1414

15-
import org.apache.commons.lang3.StringUtils;
1615
import org.flowable.cmmn.api.delegate.DelegatePlanItemInstance;
1716
import org.flowable.cmmn.api.delegate.PlanItemJavaDelegate;
1817
import org.flowable.cmmn.engine.CmmnEngineConfiguration;
@@ -35,17 +34,7 @@ public void execute(DelegatePlanItemInstance planItemInstance) {
3534
@Override
3635
protected FlowableMailClient getMailClient(DelegatePlanItemInstance planItemInstance) {
3736
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration();
38-
String tenantId = planItemInstance.getTenantId();
39-
FlowableMailClient mailClient = null;
40-
if (StringUtils.isNotBlank(tenantId)) {
41-
mailClient = cmmnEngineConfiguration.getMailClient(tenantId);
42-
}
43-
44-
if (mailClient == null) {
45-
mailClient = cmmnEngineConfiguration.getDefaultMailClient();
46-
}
47-
48-
return mailClient;
37+
return cmmnEngineConfiguration.getMailClientProvider().getMailClient(planItemInstance.getTenantId());
4938
}
5039

5140
@Override
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.cmmn.test.task;
14+
15+
import java.util.HashMap;
16+
import java.util.Map;
17+
18+
import org.flowable.cmmn.test.FlowableCmmnTestCase;
19+
import org.flowable.common.engine.impl.cfg.mail.MailServerInfo;
20+
import org.flowable.mail.common.api.client.MailClientProvider;
21+
import org.junit.jupiter.api.AfterAll;
22+
import org.junit.jupiter.api.AfterEach;
23+
import org.junit.jupiter.api.BeforeAll;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Tag;
26+
import org.subethamail.wiser.Wiser;
27+
28+
/**
29+
* @author Valentin Zickner
30+
*/
31+
@Tag("email")
32+
public abstract class CmmnEmailTestCase extends FlowableCmmnTestCase {
33+
34+
protected static Wiser wiser;
35+
private MailClientProvider initialMailClientProvider;
36+
private Map<String, MailServerInfo> initialMailServers;
37+
38+
@BeforeAll
39+
public static void setupWiser() throws Exception {
40+
int counter = 0;
41+
boolean serverUpAndRunning = false;
42+
while (!serverUpAndRunning && counter++ < 11) {
43+
wiser = Wiser.port(5025);
44+
try {
45+
wiser.start();
46+
serverUpAndRunning = true;
47+
} catch (RuntimeException e) { // Fix for slow port-closing Jenkins
48+
if (e.getMessage().toLowerCase().contains("bindexception")) {
49+
Thread.sleep(250L);
50+
}
51+
}
52+
}
53+
}
54+
55+
@BeforeEach
56+
public void setUp() {
57+
wiser.getMessages().clear();
58+
initialMailClientProvider = cmmnEngineConfiguration.getMailClientProvider();
59+
reinitializeMailClients();
60+
Map<String, MailServerInfo> mailServers = cmmnEngineConfiguration.getMailServers();
61+
initialMailServers = mailServers == null ? null : new HashMap<>(mailServers);
62+
}
63+
64+
@AfterEach
65+
public void tearDown() {
66+
if (initialMailServers != null) {
67+
cmmnEngineConfiguration.getMailServers().clear();
68+
cmmnEngineConfiguration.getMailServers().putAll(initialMailServers);
69+
}
70+
cmmnEngineConfiguration.setMailClientProvider(initialMailClientProvider);
71+
}
72+
73+
@AfterAll
74+
public static void stopWiser() {
75+
wiser.stop();
76+
}
77+
78+
protected void reinitializeMailClients() {
79+
cmmnEngineConfiguration.setMailClientProvider(null);
80+
cmmnEngineConfiguration.initMailClients();
81+
}
82+
83+
protected void addMailServer(String tenantId, String defaultFrom, String forceTo) {
84+
MailServerInfo mailServerInfo = new MailServerInfo();
85+
mailServerInfo.setMailServerHost("localhost");
86+
mailServerInfo.setMailServerPort(5025);
87+
mailServerInfo.setMailServerUseSSL(false);
88+
mailServerInfo.setMailServerUseTLS(false);
89+
mailServerInfo.setMailServerDefaultFrom(defaultFrom);
90+
mailServerInfo.setMailServerForceTo(forceTo);
91+
mailServerInfo.setMailServerUsername(defaultFrom);
92+
mailServerInfo.setMailServerPassword("password");
93+
94+
cmmnEngineConfiguration.getMailServers().put(tenantId, mailServerInfo);
95+
}
96+
97+
}

modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/task/CmmnMailTaskTest.java

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,57 +33,17 @@
3333

3434
import org.apache.commons.lang3.Validate;
3535
import org.flowable.cmmn.engine.test.CmmnDeployment;
36-
import org.flowable.cmmn.test.FlowableCmmnTestCase;
3736
import org.flowable.common.engine.impl.cfg.mail.FlowableMailClientCreator;
3837
import org.flowable.common.engine.impl.cfg.mail.MailServerInfo;
39-
import org.junit.jupiter.api.AfterAll;
40-
import org.junit.jupiter.api.BeforeAll;
41-
import org.junit.jupiter.api.BeforeEach;
42-
import org.junit.jupiter.api.Tag;
4338
import org.junit.jupiter.api.Test;
44-
import org.subethamail.wiser.Wiser;
4539
import org.subethamail.wiser.WiserMessage;
4640

4741
import tools.jackson.databind.node.ArrayNode;
4842

4943
/**
5044
* @author Joram Barrez
5145
*/
52-
@Tag("email")
53-
public class CmmnMailTaskTest extends FlowableCmmnTestCase {
54-
55-
protected static Wiser wiser;
56-
57-
@BeforeAll
58-
public static void setupWiser() throws Exception {
59-
wiser = Wiser.port(5025);
60-
61-
int counter = 0;
62-
boolean serverUpAndRunning = false;
63-
while (!serverUpAndRunning && counter++ < 11) {
64-
65-
wiser = Wiser.port(5025);
66-
67-
try {
68-
wiser.start();
69-
serverUpAndRunning = true;
70-
} catch (RuntimeException e) { // Fix for slow port-closing Jenkins
71-
if (e.getMessage().toLowerCase().contains("bindexception")) {
72-
Thread.sleep(250L);
73-
}
74-
}
75-
}
76-
}
77-
78-
@BeforeEach
79-
public void resetMessages() {
80-
wiser.getMessages().clear();
81-
}
82-
83-
@AfterAll
84-
public static void stopWiser() {
85-
wiser.stop();
86-
}
46+
public class CmmnMailTaskTest extends CmmnEmailTestCase {
8747

8848
@Test
8949
@CmmnDeployment

0 commit comments

Comments
 (0)