Merge pull request #44290 from nosan

* pr/44290:
  Polish "Auto-configure ObjectDirectoryMapper"
  Auto-configure ObjectDirectoryMapper

Closes gh-44290
This commit is contained in:
Stéphane Nicoll
2025-02-17 12:02:57 +01:00
2 changed files with 53 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,13 +26,17 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.ldap.LdapProperties.Template;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.ldap.convert.ConverterUtils;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.DirContextAuthenticationStrategy;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper;
/**
* {@link EnableAutoConfiguration Auto-configuration} for LDAP.
@@ -70,12 +74,24 @@ public class LdapAutoConfiguration {
return source;
}
@Bean
@ConditionalOnMissingBean
public ObjectDirectoryMapper objectDirectoryMapper() {
ApplicationConversionService conversionService = new ApplicationConversionService();
ConverterUtils.addDefaultConverters(conversionService);
DefaultObjectDirectoryMapper objectDirectoryMapper = new DefaultObjectDirectoryMapper();
objectDirectoryMapper.setConversionService(conversionService);
return objectDirectoryMapper;
}
@Bean
@ConditionalOnMissingBean(LdapOperations.class)
public LdapTemplate ldapTemplate(LdapProperties properties, ContextSource contextSource) {
public LdapTemplate ldapTemplate(LdapProperties properties, ContextSource contextSource,
ObjectDirectoryMapper objectDirectoryMapper) {
Template template = properties.getTemplate();
PropertyMapper propertyMapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
ldapTemplate.setObjectDirectoryMapper(objectDirectoryMapper);
propertyMapper.from(template.isIgnorePartialResultException())
.to(ldapTemplate::setIgnorePartialResultException);
propertyMapper.from(template.isIgnoreNameNotFoundException()).to(ldapTemplate::setIgnoreNameNotFoundException);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
package org.springframework.boot.autoconfigure.ldap;
import javax.naming.Name;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -27,6 +31,7 @@ import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.DirContextAuthenticationStrategy;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.pool2.factory.PoolConfig;
import org.springframework.ldap.pool2.factory.PooledContextSource;
import org.springframework.ldap.support.LdapUtils;
@@ -132,6 +137,21 @@ class LdapAutoConfigurationTests {
});
}
@Test
void objectDirectoryMapperExists() {
this.contextRunner.withPropertyValues("spring.ldap.urls:ldap://localhost:389").run((context) -> {
assertThat(context).hasSingleBean(ObjectDirectoryMapper.class);
ObjectDirectoryMapper objectDirectoryMapper = context.getBean(ObjectDirectoryMapper.class);
ApplicationConversionService conversionService = assertThat(objectDirectoryMapper)
.extracting("converterManager")
.extracting("conversionService")
.asInstanceOf(InstanceOfAssertFactories.type(ApplicationConversionService.class))
.actual();
assertThat(conversionService.canConvert(String.class, Name.class)).isTrue();
assertThat(conversionService.canConvert(Name.class, String.class)).isTrue();
});
}
@Test
void templateExists() {
this.contextRunner.withPropertyValues("spring.ldap.urls:ldap://localhost:389").run((context) -> {
@@ -140,9 +160,23 @@ class LdapAutoConfigurationTests {
assertThat(ldapTemplate).hasFieldOrPropertyWithValue("ignorePartialResultException", false);
assertThat(ldapTemplate).hasFieldOrPropertyWithValue("ignoreNameNotFoundException", false);
assertThat(ldapTemplate).hasFieldOrPropertyWithValue("ignoreSizeLimitExceededException", true);
assertThat(ldapTemplate).extracting("objectDirectoryMapper")
.isSameAs(context.getBean(ObjectDirectoryMapper.class));
});
}
@Test
void templateCanBeConfiguredWithCustomObjectDirectoryMapper() {
ObjectDirectoryMapper objectDirectoryMapper = mock(ObjectDirectoryMapper.class);
this.contextRunner.withPropertyValues("spring.ldap.urls:ldap://localhost:389")
.withBean(ObjectDirectoryMapper.class, () -> objectDirectoryMapper)
.run((context) -> {
assertThat(context).hasSingleBean(LdapTemplate.class);
LdapTemplate ldapTemplate = context.getBean(LdapTemplate.class);
assertThat(ldapTemplate).extracting("objectDirectoryMapper").isSameAs(objectDirectoryMapper);
});
}
@Test
void templateConfigurationCanBeCustomized() {
this.contextRunner