SpEL not supported in Spring annotation @Entry.base

java, spring, spring-boot, spring-el, spring-ldap

Solution

Turns out the reason I needed a different `base` in the first place is because Spring was not setting the `base` on the `ContextSource`.

When you let Spring Boot autoconfigure the embedded LDAP server, it creates a `ContextSource` as such in `EmbeddedLdapAutoConfiguration`:

@Bean
@DependsOn("directoryServer")
@ConditionalOnMissingBean
public ContextSource ldapContextSource() {
    LdapContextSource source = new LdapContextSource();
    if (hasCredentials(this.embeddedProperties.getCredential())) {
        source.setUserDn(this.embeddedProperties.getCredential().getUsername());
        source.setPassword(this.embeddedProperties.getCredential().getPassword());
    }
    source.setUrls(this.properties.determineUrls(this.environment));
    return source;
}

As you can see, nowhere in there does it call `source.setBase()`. So to solve this, I added a configuration file with `@Profile("embedded")` and manually created a `ContextSource` where I set the `base` myself (I leave off the credentials part because I don't use credentials for the embedded server):

@Configuration
@Profile("embedded")
@EnableConfigurationProperties({ LdapProperties.class })
public class EmbeddedLdapConfig {

    private final Environment environment;
    private final LdapProperties properties;

    public EmbeddedLdapConfig(final Environment environment, final LdapProperties properties) {
        this.environment = environment;
        this.properties = properties;
    }

    @Bean
    @DependsOn("directoryServer")
    public ContextSource ldapContextSource() {
        final LdapContextSource source = new LdapContextSource();
        source.setUrls(this.properties.determineUrls(this.environment));
        source.setBase(this.properties.getBase());
        return source;
    }
}

Now, I can leave the value of the `base` attribute in my `@Entry` the same for both the Active Directory server and the embedded UnboundID server and it works properly.

Problem

I use Spring Data LDAP and Spring Boot provides out of the box support for an embedded UnboundID server. However, when I use Spring Data LDAP's `@Entry` annotation, I need to specify a different `base` in the annotation based on whether I'm using the embedded UnboundID LDAP server, or a remote Active Directory server. I was attempting to do this with SpEL and profile-based properties by specifying: ``` @Entry(base = "${ldap.person.base}", ...) ``` Then I have an `application.propreties` with `ldap.person.base=OU=AD Person Base` and an `application-embedded.properties` with `ldap.person.base=OU=Embedded Person Base`. However, the `@Entry` annotation does not seem to support SpEL evaluation: javax.naming.InvalidNameException: Invalid name: ${ldap.person.base} There is an open issue in Spring LDAP to add support for this, but is there any workaround or some other way I can accomplish this until it is supported in Spring LDAP?

Original source