LdaptiveConnectionConfigFactory.java
/*
* Copyright 2019 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bremersee.data.ldaptive;
import static org.springframework.util.Assert.notNull;
import java.util.function.Predicate;
import org.ldaptive.BindConnectionInitializer;
import org.ldaptive.ClosedRetryMetadata;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.ConnectionInitializer;
import org.ldaptive.Credential;
import org.ldaptive.RetryMetadata;
import org.ldaptive.ssl.CredentialConfig;
import org.ldaptive.ssl.SslConfig;
import org.ldaptive.ssl.X509CredentialConfig;
import org.springframework.util.StringUtils;
/**
* The connection config factory.
*
* @author Christian Bremer
*/
@SuppressWarnings("unused")
public interface LdaptiveConnectionConfigFactory {
/**
* Create connection config.
*
* @param properties the properties
* @return the connection config
*/
default ConnectionConfig createConnectionConfig(LdaptiveProperties properties) {
notNull(properties, "Ldaptive properties must not be null.");
return createConnectionConfig(
properties,
properties.getBindDn(),
properties.getBindCredentials());
}
/**
* Create connection config.
*
* @param properties the properties
* @param bindDn the bind dn
* @param bindCredential the bind credential
* @return the connection config
*/
ConnectionConfig createConnectionConfig(
LdaptiveProperties properties,
String bindDn,
String bindCredential);
/**
* Get default connection config factory.
*
* @return the default connection config factory
*/
static LdaptiveConnectionConfigFactory defaultFactory() {
return new Default();
}
/**
* The default connection config factory.
*/
class Default implements LdaptiveConnectionConfigFactory {
@Override
public ConnectionConfig createConnectionConfig(
final LdaptiveProperties properties,
final String bindDn,
final String bindCredentials) {
notNull(properties, "Ldaptive properties must not be null.");
return ConnectionConfig.builder()
.autoReconnect(properties.isAutoReconnect())
.autoReconnectCondition(autoReconnectCondition(properties))
.autoReplay(properties.isAutoReplay())
.connectionInitializers(connectionInitializers(properties, bindDn, bindCredentials))
.connectTimeout(properties.getConnectTimeout())
.reconnectTimeout(properties.getReconnectTimeout())
.responseTimeout(properties.getResponseTimeout())
.sslConfig(sslConfig(properties))
.url(properties.getLdapUrl())
.useStartTLS(properties.isUseStartTls())
.build();
}
private Predicate<RetryMetadata> autoReconnectCondition(LdaptiveProperties properties) {
return metadata -> {
if (properties.getReconnectAttempts() > 0 && metadata instanceof ClosedRetryMetadata) {
if (metadata.getAttempts() > properties.getReconnectAttempts()) {
return false;
}
if (metadata.getAttempts() > 0) {
try {
long delay = Math.abs(properties.getReconnectBackoffDelay().toMillis());
double multiplier = Math.abs(properties.getReconnectBackoffMultiplier() * metadata.getAttempts());
int attempts = metadata.getAttempts();
long millis = Math.round(delay * multiplier * attempts);
Thread.sleep(millis);
} catch (InterruptedException e) {
// nothing to do
}
}
return true;
}
return false;
};
}
private ConnectionInitializer[] connectionInitializers(
LdaptiveProperties properties,
String bindDn,
String bindCredentials) {
String username;
String password;
if (StringUtils.hasText(bindDn)) {
username = bindDn;
password = bindCredentials;
} else {
username = properties.getBindDn();
password = properties.getBindCredentials();
}
if (StringUtils.hasText(username)) {
return new ConnectionInitializer[]{
connectionInitializer(username, password)
};
}
return new ConnectionInitializer[]{};
}
private ConnectionInitializer connectionInitializer(String bindDn, String bindCredential) {
// sasl is not supported at the moment
final BindConnectionInitializer bci = new BindConnectionInitializer();
bci.setBindDn(bindDn);
bci.setBindCredential(new Credential(bindCredential));
return bci;
}
private SslConfig sslConfig(LdaptiveProperties properties) {
if (hasSslConfig(properties)) {
SslConfig sc = new SslConfig();
sc.setCredentialConfig(sslCredentialConfig(properties));
return sc;
}
return null;
}
private boolean hasSslConfig(LdaptiveProperties properties) {
return StringUtils.hasText(properties.getTrustCertificates())
|| StringUtils.hasText(properties.getAuthenticationCertificate())
|| StringUtils.hasText(properties.getAuthenticationKey());
}
private CredentialConfig sslCredentialConfig(LdaptiveProperties properties) {
X509CredentialConfig x509 = new X509CredentialConfig();
if (StringUtils.hasText(properties.getAuthenticationCertificate())) {
x509.setAuthenticationCertificate(properties.getAuthenticationCertificate());
}
if (StringUtils.hasText(properties.getAuthenticationKey())) {
x509.setAuthenticationKey(properties.getAuthenticationKey());
}
if (StringUtils.hasText(properties.getTrustCertificates())) {
x509.setTrustCertificates(properties.getTrustCertificates());
}
return x509;
}
}
}