1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.data.ldaptive;
18
19 import lombok.extern.slf4j.Slf4j;
20 import org.bremersee.data.ldaptive.reactive.ReactiveLdaptiveOperations;
21 import org.bremersee.data.ldaptive.reactive.ReactiveLdaptiveTemplate;
22 import org.bremersee.exception.ServiceException;
23 import org.ldaptive.ConnectionFactory;
24 import org.ldaptive.DefaultConnectionFactory;
25 import org.ldaptive.PooledConnectionFactory;
26 import org.ldaptive.SearchRequest;
27 import org.ldaptive.SearchResponse;
28 import org.ldaptive.pool.IdlePruneStrategy;
29 import org.springframework.beans.factory.ObjectProvider;
30 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
31 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
32 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
33 import org.springframework.boot.context.event.ApplicationReadyEvent;
34 import org.springframework.boot.context.properties.EnableConfigurationProperties;
35 import org.springframework.context.annotation.Bean;
36 import org.springframework.context.annotation.Configuration;
37 import org.springframework.context.event.EventListener;
38 import org.springframework.util.ClassUtils;
39
40
41
42
43
44
45 @Configuration
46 @ConditionalOnClass({
47 ConnectionFactory.class,
48 LdaptiveTemplate.class
49 })
50 @ConditionalOnProperty(prefix = "bremersee.ldaptive", name = "enabled", havingValue = "true")
51 @EnableConfigurationProperties(LdaptiveProperties.class)
52 @Slf4j
53 public class LdaptiveAutoConfiguration {
54
55 private final LdaptiveProperties properties;
56
57 private final LdaptiveConnectionConfigFactory connectionConfigFactory;
58
59
60
61
62
63
64
65 public LdaptiveAutoConfiguration(
66 LdaptiveProperties ldaptiveProperties,
67 ObjectProvider<LdaptiveConnectionConfigFactory> connectionConfigFactory) {
68 this.properties = ldaptiveProperties;
69 this.connectionConfigFactory = connectionConfigFactory
70 .getIfAvailable(LdaptiveConnectionConfigFactory::defaultFactory);
71 }
72
73
74
75
76 @EventListener(ApplicationReadyEvent.class)
77 public void init() {
78 log.info("\n"
79 + "*********************************************************************************\n"
80 + "* {}\n"
81 + "*********************************************************************************\n"
82 + "* connectionConfigFactory = {}\n"
83 + "* properties = {}\n"
84 + "*********************************************************************************",
85 ClassUtils.getUserClass(getClass()).getSimpleName(),
86 ClassUtils.getUserClass(connectionConfigFactory).getSimpleName(),
87 properties);
88
89 if (properties.isPooled()) {
90 log.info("Checking validation properties {}", properties.getSearchValidator());
91 LdaptiveTemplate ldaptiveTemplate = new LdaptiveTemplate(defaultConnectionFactory());
92 SearchRequest request = properties.getSearchValidator().getSearchRequest().createSearchRequest();
93 SearchResponse response = ldaptiveTemplate.search(request);
94 if (!response.isSuccess()) {
95 ServiceException se = ServiceException.internalServerError(
96 "Invalid search validator. There is no result executing search validator.",
97 "org.bremersee:common-base-ldaptive-autoconfigure:"
98 + "bf2c08f6-65bf-417c-8ab9-1c069f46bde2");
99 log.error("Validation of pool validation failed.", se);
100 throw se;
101 }
102 log.info("Checking validation properties: successfully done!");
103 }
104 }
105
106
107
108
109
110
111
112 @ConditionalOnMissingBean(LdaptiveOperations.class)
113 @Bean
114 public LdaptiveTemplate ldaptiveTemplate(ConnectionFactory connectionFactory) {
115 return new LdaptiveTemplate(connectionFactory);
116 }
117
118
119
120
121
122
123
124 @ConditionalOnClass(name = {"reactor.core.publisher.Mono"})
125 @ConditionalOnMissingBean(ReactiveLdaptiveOperations.class)
126 @Bean
127 public ReactiveLdaptiveTemplate reactiveLdaptiveTemplate(ConnectionFactory connectionFactory) {
128 return new ReactiveLdaptiveTemplate(connectionFactory);
129 }
130
131
132
133
134
135
136 @ConditionalOnMissingBean(ConnectionFactory.class)
137 @Bean(destroyMethod = "close")
138 public ConnectionFactory connectionFactory() {
139 return properties.isPooled() ? pooledConnectionFactory() : defaultConnectionFactory();
140 }
141
142 private DefaultConnectionFactory defaultConnectionFactory() {
143 return DefaultConnectionFactory.builder()
144 .config(connectionConfigFactory.createConnectionConfig(properties))
145 .build();
146 }
147
148 private PooledConnectionFactory pooledConnectionFactory() {
149 PooledConnectionFactory factory = PooledConnectionFactory.builder()
150 .config(connectionConfigFactory.createConnectionConfig(properties))
151 .blockWaitTime(properties.getBlockWaitTime())
152 .connectOnCreate(properties.isConnectOnCreate())
153 .failFastInitialize(properties.isFailFastInitialize())
154 .max(properties.getMaxPoolSize())
155 .min(properties.getMinPoolSize())
156 .pruneStrategy(new IdlePruneStrategy(properties.getPrunePeriod(), properties.getIdleTime()))
157 .validateOnCheckIn(properties.isValidateOnCheckIn())
158 .validateOnCheckOut(properties.isValidateOnCheckOut())
159 .validatePeriodically(properties.isValidatePeriodically())
160 .validator(properties.createSearchConnectionValidator())
161 .build();
162 factory.initialize();
163 return factory;
164 }
165
166 }