Skip to content

Commit d54c52f

Browse files
committed
chore: Support concurrent Citrus bean registry access
- Make sure parallel running tests are able to add beans to the Citrus registry - Add null check when adding beans as it makes no sense to add null values to the registry
1 parent c73c1a3 commit d54c52f

File tree

5 files changed

+78
-61
lines changed

5 files changed

+78
-61
lines changed

connectors/citrus-kubernetes/src/main/java/org/citrusframework/kubernetes/actions/CreateServiceAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ public CreateServiceAction doBuild() {
253253
}
254254
}
255255

256-
if (referenceResolver != null && !referenceResolver.isResolvable(serverName, HttpServer.class)) {
256+
if (httpServer != null && referenceResolver != null &&
257+
!referenceResolver.isResolvable(serverName, HttpServer.class)) {
257258
referenceResolver.bind(serverName, httpServer);
258259
}
259260

core/citrus-api/src/main/java/org/citrusframework/spi/SimpleReferenceResolver.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package org.citrusframework.spi;
1818

19-
import java.util.HashMap;
2019
import java.util.Map;
20+
import java.util.concurrent.ConcurrentHashMap;
2121
import java.util.stream.Collectors;
2222

2323
import org.citrusframework.exceptions.CitrusRuntimeException;
@@ -27,7 +27,7 @@
2727
*/
2828
public class SimpleReferenceResolver implements ReferenceResolver, ReferenceRegistry {
2929

30-
private final Map<String, Object> objectStore = new HashMap<>();
30+
private final ConcurrentHashMap<String, Object> objectStore = new ConcurrentHashMap<>();
3131

3232
@Override
3333
public <T> T resolve(Class<T> type) {
@@ -85,6 +85,8 @@ public boolean isResolvable(String name, Class<?> type) {
8585

8686
@Override
8787
public void bind(String name, Object value) {
88-
this.objectStore.put(name, value);
88+
if (value != null) {
89+
this.objectStore.put(name, value);
90+
}
8991
}
9092
}

core/citrus-base/src/main/java/org/citrusframework/CitrusContext.java

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -361,72 +361,84 @@ public void handleTestResults(TestResults testResults) {
361361
}
362362

363363
public void addComponent(String name, Object component) {
364+
if (component == null) {
365+
return;
366+
}
367+
368+
if (component instanceof ReferenceResolverAware referenceResolverAware) {
369+
referenceResolverAware.setReferenceResolver(referenceResolver);
370+
}
371+
364372
if (component instanceof InitializingPhase c) {
365373
c.initialize();
366374
}
375+
367376
referenceResolver.bind(name, component);
368377

369-
if (component instanceof MessageValidator<?> messageValidator) {
370-
messageValidatorRegistry.addMessageValidator(name, messageValidator);
371-
testContextFactory.getMessageValidatorRegistry().addMessageValidator(name, messageValidator);
372-
}
378+
synchronized (this) {
379+
if (component instanceof MessageValidator<?> messageValidator) {
380+
messageValidatorRegistry.addMessageValidator(name, messageValidator);
381+
testContextFactory.getMessageValidatorRegistry().addMessageValidator(name, messageValidator);
382+
}
373383

374-
if (component instanceof MessageProcessor messageProcessor) {
375-
messageProcessors.addMessageProcessor(messageProcessor);
376-
testContextFactory.getMessageProcessors().addMessageProcessor(messageProcessor);
377-
}
384+
if (component instanceof MessageProcessor messageProcessor) {
385+
messageProcessors.addMessageProcessor(messageProcessor);
386+
testContextFactory.getMessageProcessors().addMessageProcessor(messageProcessor);
387+
}
378388

379-
if (component instanceof TestSuiteListener suiteListener) {
380-
testSuiteListeners.addTestSuiteListener(suiteListener);
381-
}
389+
if (component instanceof TestSuiteListener suiteListener) {
390+
testSuiteListeners.addTestSuiteListener(suiteListener);
391+
}
382392

383-
if (component instanceof TestListener testListener) {
384-
testListeners.addTestListener(testListener);
385-
testContextFactory.getTestListeners().addTestListener(testListener);
386-
}
393+
if (component instanceof TestListener testListener) {
394+
testListeners.addTestListener(testListener);
395+
testContextFactory.getTestListeners().addTestListener(testListener);
396+
}
387397

388-
if (component instanceof TestReporter testReporter) {
389-
testReporters.addTestReporter(testReporter);
390-
}
398+
if (component instanceof TestReporter testReporter) {
399+
testReporters.addTestReporter(testReporter);
400+
}
391401

392-
if (component instanceof TestActionListener testActionListener) {
393-
testActionListeners.addTestActionListener(testActionListener);
394-
testContextFactory.getTestActionListeners().addTestActionListener(testActionListener);
395-
}
402+
if (component instanceof TestActionListener testActionListener) {
403+
testActionListeners.addTestActionListener(testActionListener);
404+
testContextFactory.getTestActionListeners().addTestActionListener(testActionListener);
405+
}
396406

397-
if (component instanceof MessageListener messageListener) {
398-
messageListeners.addMessageListener(messageListener);
399-
testContextFactory.getMessageListeners().addMessageListener(messageListener);
400-
}
407+
if (component instanceof MessageListener messageListener) {
408+
messageListeners.addMessageListener(messageListener);
409+
testContextFactory.getMessageListeners().addMessageListener(messageListener);
410+
}
401411

402-
if (component instanceof BeforeTest beforeTest) {
403-
testContextFactory.getBeforeTest().add(beforeTest);
404-
}
412+
if (component instanceof BeforeTest beforeTest) {
413+
testContextFactory.getBeforeTest().add(beforeTest);
414+
}
405415

406-
if (component instanceof AfterTest afterTest) {
407-
testContextFactory.getAfterTest().add(afterTest);
408-
}
416+
if (component instanceof AfterTest afterTest) {
417+
testContextFactory.getAfterTest().add(afterTest);
418+
}
409419

410-
if (component instanceof BeforeSuite beforeSuiteComponent) {
411-
beforeSuite.add(beforeSuiteComponent);
412-
}
420+
if (component instanceof BeforeSuite beforeSuiteComponent) {
421+
beforeSuite.add(beforeSuiteComponent);
422+
}
413423

414-
if (component instanceof AfterSuite afterSuiteComponent) {
415-
afterSuite.add(afterSuiteComponent);
416-
}
424+
if (component instanceof AfterSuite afterSuiteComponent) {
425+
afterSuite.add(afterSuiteComponent);
426+
}
417427

418-
if (component instanceof FunctionLibrary library) {
419-
functionRegistry.addFunctionLibrary(library);
420-
testContextFactory.getFunctionRegistry().addFunctionLibrary(library);
421-
}
428+
if (component instanceof FunctionLibrary library) {
429+
functionRegistry.addFunctionLibrary(library);
430+
testContextFactory.getFunctionRegistry().addFunctionLibrary(library);
431+
}
422432

423-
if (component instanceof ValidationMatcherLibrary library) {
424-
validationMatcherRegistry.addValidationMatcherLibrary(library);
425-
testContextFactory.getValidationMatcherRegistry().addValidationMatcherLibrary(library);
426-
}
433+
if (component instanceof ValidationMatcherLibrary library) {
434+
validationMatcherRegistry.addValidationMatcherLibrary(library);
435+
testContextFactory.getValidationMatcherRegistry().addValidationMatcherLibrary(library);
436+
}
427437

428-
if (component instanceof ReferenceResolverAware referenceResolverAware) {
429-
referenceResolverAware.setReferenceResolver(referenceResolver);
438+
if (component instanceof GlobalVariables vars) {
439+
globalVariables.getVariables().putAll(vars.getVariables());
440+
testContextFactory.getGlobalVariables().getVariables().putAll(vars.getVariables());
441+
}
430442
}
431443
}
432444

core/citrus-base/src/main/java/org/citrusframework/annotations/CitrusAnnotations.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,9 @@ public static void parseConfiguration(Object configuration, CitrusContext citrus
246246
try {
247247
String name = ReferenceRegistry.getName(m.getAnnotation(BindToRegistry.class), m.getName());
248248
Object component = m.invoke(configuration);
249-
250-
if (component instanceof Named named) {
249+
if (component == null) {
250+
return;
251+
} if (component instanceof Named named) {
251252
named.setName(name);
252253
}
253254

@@ -270,8 +271,9 @@ public static void parseConfiguration(Object configuration, CitrusContext citrus
270271
try {
271272
String name = ReferenceRegistry.getName(f.getAnnotation(BindToRegistry.class), f.getName());
272273
Object component = f.get(configuration);
273-
274-
if (component instanceof Named named) {
274+
if (component == null) {
275+
return;
276+
} else if (component instanceof Named named) {
275277
named.setName(name);
276278
}
277279

core/citrus-base/src/main/java/org/citrusframework/container/AbstractTestBoundaryActionContainer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,35 +72,35 @@ public boolean shouldExecute(String testName, String packageName, String[] inclu
7272

7373
if (StringUtils.hasText(packageNamePattern)) {
7474
if (!Pattern.compile(packageNamePattern).matcher(packageName).matches()) {
75-
logger.warn(String.format(baseErrorMessage, "test package", getName()));
75+
logger.debug(String.format(baseErrorMessage, "test package", getName()));
7676
return false;
7777
}
7878
}
7979

8080
if (StringUtils.hasText(namePattern)) {
8181
if (!Pattern.compile(sanitizePatten(namePattern)).matcher(testName).matches()) {
82-
logger.warn(String.format(baseErrorMessage, "test name", getName()));
82+
logger.debug(String.format(baseErrorMessage, "test name", getName()));
8383
return false;
8484
}
8585
}
8686

8787
if (!checkTestGroups(includedGroups)) {
88-
logger.warn(String.format(baseErrorMessage, "test groups", getName()));
88+
logger.debug(String.format(baseErrorMessage, "test groups", getName()));
8989
return false;
9090
}
9191

9292
for (Map.Entry<String, String> envEntry : env.entrySet()) {
9393
if (!System.getenv().containsKey(envEntry.getKey()) ||
9494
(StringUtils.hasText(envEntry.getValue()) && !System.getenv().get(envEntry.getKey()).equals(envEntry.getValue()))) {
95-
logger.warn(String.format(baseErrorMessage, "env properties", getName()));
95+
logger.debug(String.format(baseErrorMessage, "env properties", getName()));
9696
return false;
9797
}
9898
}
9999

100100
for (Map.Entry<String, String> systemProperty : systemProperties.entrySet()) {
101101
if (!System.getProperties().containsKey(systemProperty.getKey()) ||
102102
(StringUtils.hasText(systemProperty.getValue()) && !System.getProperties().get(systemProperty.getKey()).equals(systemProperty.getValue()))) {
103-
logger.warn(String.format(baseErrorMessage, "system properties", getName()));
103+
logger.debug(String.format(baseErrorMessage, "system properties", getName()));
104104
return false;
105105
}
106106
}

0 commit comments

Comments
 (0)