1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.util.pool;
35
36 import java.io.InputStream;
37 import java.sql.Connection;
38 import java.util.Collection;
39 import java.util.Enumeration;
40 import java.util.HashMap;
41 import java.util.Hashtable;
42 import java.util.Map;
43 import java.util.Map.Entry;
44 import java.util.Properties;
45
46 import javax.sql.DataSource;
47
48 import org.apache.logging.log4j.LogManager;
49 import org.apache.logging.log4j.Logger;
50
51 import fr.paris.lutece.portal.service.init.LuteceInitException;
52 import fr.paris.lutece.portal.service.util.AppPropertiesService;
53 import fr.paris.lutece.util.ReferenceList;
54 import fr.paris.lutece.util.pool.service.ConnectionService;
55 import fr.paris.lutece.util.pool.service.LuteceConnectionService;
56
57
58
59
60
61 public final class PoolManager
62 {
63 private static final String LOGGER_NAME = "lutece.pool";
64 private static PoolManager _instance;
65 private Logger _logger;
66 private Map<String, ConnectionService> _pools = new HashMap<>( );
67
68
69
70
71
72
73
74
75
76
77 private PoolManager( InputStream isDbProperties ) throws LuteceInitException
78 {
79 init( isDbProperties );
80 }
81
82
83
84
85
86
87
88
89
90
91 public static synchronized PoolManager getInstance( InputStream isDbProperties ) throws LuteceInitException
92 {
93 if ( _instance == null )
94 {
95 _instance = new PoolManager( isDbProperties );
96 }
97
98 return _instance;
99 }
100
101
102
103
104
105
106
107
108
109 private void init( InputStream is ) throws LuteceInitException
110 {
111 _logger = LogManager.getLogger( LOGGER_NAME );
112
113 Properties dbProps = new Properties( );
114
115 try
116 {
117 dbProps.load( is );
118 }
119 catch( Exception e )
120 {
121 throw new LuteceInitException( "Can't read the properties file. Make sure db.properties is in the CLASSPATH", e );
122 }
123
124 overrideProperties(dbProps);
125 createPools( dbProps );
126 }
127
128
129
130
131
132 private void overrideProperties(Properties dbProps) {
133 Enumeration propertiesName= dbProps.propertyNames();
134 while (propertiesName.hasMoreElements()) {
135 String key = (String) propertiesName.nextElement();
136 String value= AppPropertiesService.getProperty(key);
137 if( value != null ) {
138 dbProps.put(key, value);
139 }
140 }
141 }
142
143
144
145
146
147
148
149
150
151 private void createPools( Properties props ) throws LuteceInitException
152 {
153 Enumeration propNames = props.propertyNames( );
154 String strPoolName = "";
155
156 Map<String, Hashtable<String, String>> htPools = new HashMap<>( );
157
158 while ( propNames.hasMoreElements( ) )
159 {
160 String name = (String) propNames.nextElement( );
161
162 try
163 {
164 strPoolName = name.substring( 0, name.lastIndexOf( '.' ) );
165
166
167 Hashtable<String, String> htParamsPool = htPools.computeIfAbsent( strPoolName, s -> new Hashtable<>( ) );
168 htParamsPool.put( name, props.getProperty( name ) );
169 htPools.put( strPoolName, htParamsPool );
170
171 _logger.debug( "property {}", name );
172 _logger.debug( "pool name {}", strPoolName );
173 }
174 catch( Exception e )
175 {
176 throw new LuteceInitException( "Invalid initialization of the pools. Problem encoutered with the property : " + name, e );
177 }
178 }
179
180 for ( Entry<String, Hashtable<String, String>> entry : htPools.entrySet( ) )
181 {
182 String key = entry.getKey( );
183 try
184 {
185 Hashtable<String, String> htParamsPool = htPools.get( key );
186 ConnectionService cs = getConnectionService( htParamsPool, key );
187
188 if ( cs != null )
189 {
190 cs.setPoolName( key );
191 cs.setLogger( _logger );
192 cs.init( htParamsPool );
193 _pools.put( key, cs );
194 }
195 }
196 catch( Exception e )
197 {
198 throw new LuteceInitException( "Exception when getting the pool '" + key + "'. Please check your '/WEB-INF/conf/db.properties' file.", e );
199 }
200 }
201 }
202
203 private ConnectionService getConnectionService( Map<String, String> htParamsPool, String key ) throws LuteceInitException
204 {
205 ConnectionService cs = null;
206
207 try
208 {
209 String strConnectionService = htParamsPool.get( key + ".poolservice" );
210
211 cs = (ConnectionService) Class.forName( strConnectionService ).newInstance( );
212 }
213 catch( NullPointerException nullEx )
214 {
215 cs = new LuteceConnectionService( );
216 }
217 catch( Exception e )
218 {
219 throw new LuteceInitException( "Exception when getting the property poolservice", e );
220 }
221 return cs;
222 }
223
224
225
226
227
228
229
230
231 public Connection getConnection( String strPoolName )
232 {
233 Connection conn = null;
234 ConnectionService pool = _pools.get( strPoolName );
235
236 if ( pool != null )
237 {
238 conn = pool.getConnection( );
239 }
240
241 return conn;
242 }
243
244
245
246
247
248
249
250
251
252 public void freeConnection( String strPoolName, Connection con )
253 {
254 ConnectionService cs = _pools.get( strPoolName );
255
256 if ( cs != null )
257 {
258 cs.freeConnection( con );
259 }
260 }
261
262
263
264
265 public synchronized void release( )
266 {
267 for ( ConnectionService pool : _pools.values( ) )
268 {
269 pool.release( );
270 }
271 }
272
273
274
275
276
277
278 public Collection<ConnectionService> getPools( )
279 {
280 return _pools.values( );
281 }
282
283
284
285
286
287
288 public ReferenceList getPoolsInfos( )
289 {
290 ReferenceListReferenceList">ReferenceList listPoolsInfos = new ReferenceList( );
291 Collection<ConnectionService> listPools = getPools( );
292
293 for ( ConnectionService cs : listPools )
294 {
295 String strCurrentConnections = ( cs.getCurrentConnections( ) == ConnectionService.INFO_NOT_AVAILABLE ) ? "-" : ( "" + cs.getCurrentConnections( ) );
296 String strMaxConnections = ( cs.getMaxConnections( ) == ConnectionService.INFO_NOT_AVAILABLE ) ? "-" : ( "" + cs.getMaxConnections( ) );
297 listPoolsInfos.addItem( cs.getPoolName( ), strCurrentConnections + " / " + strMaxConnections + " (" + cs.getPoolProvider( ) + ")" );
298 }
299
300 return listPoolsInfos;
301 }
302
303
304
305
306
307
308
309
310 public DataSource getDataSource( String strPoolName )
311 {
312 return _pools.get( strPoolName ).getDataSource( );
313 }
314 }