1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbcp2.datasources;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.sql.Connection;
22 import java.sql.SQLException;
23 import java.time.Duration;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.NoSuchElementException;
27 import java.util.function.Supplier;
28
29 import javax.naming.NamingException;
30 import javax.naming.Reference;
31 import javax.naming.StringRefAddr;
32 import javax.sql.ConnectionPoolDataSource;
33
34 import org.apache.commons.dbcp2.SwallowedExceptionLogger;
35 import org.apache.commons.dbcp2.Utils;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.commons.pool2.ObjectPool;
39 import org.apache.commons.pool2.impl.EvictionPolicy;
40 import org.apache.commons.pool2.impl.GenericObjectPool;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class PerUserPoolDataSource extends InstanceKeyDataSource {
62
63 private static final long serialVersionUID = 7872747993848065028L;
64
65 private static final Log log = LogFactory.getLog(PerUserPoolDataSource.class);
66
67 private static <K, V> HashMap<K, V> createMap() {
68
69 return new HashMap<>();
70 }
71
72
73
74
75 private Map<String, Boolean> perUserBlockWhenExhausted;
76
77
78
79
80 private Map<String, String> perUserEvictionPolicyClassName;
81
82
83
84
85 private Map<String, Boolean> perUserLifo;
86
87
88
89
90 private Map<String, Integer> perUserMaxIdle;
91
92
93
94
95 private Map<String, Integer> perUserMaxTotal;
96
97
98
99
100 private Map<String, Duration> perUserMaxWaitDuration;
101
102
103
104
105 private Map<String, Duration> perUserMinEvictableIdleDuration;
106
107
108
109
110 private Map<String, Integer> perUserMinIdle;
111
112
113
114
115 private Map<String, Integer> perUserNumTestsPerEvictionRun;
116
117
118
119
120 private Map<String, Duration> perUserSoftMinEvictableIdleDuration;
121
122
123
124
125 private Map<String, Boolean> perUserTestOnCreate;
126
127
128
129
130 private Map<String, Boolean> perUserTestOnBorrow;
131
132
133
134
135 private Map<String, Boolean> perUserTestOnReturn;
136
137
138
139
140 private Map<String, Boolean> perUserTestWhileIdle;
141
142
143
144
145 private Map<String, Duration> perUserDurationBetweenEvictionRuns;
146
147
148
149
150 private Map<String, Boolean> perUserDefaultAutoCommit;
151
152
153
154
155 private Map<String, Integer> perUserDefaultTransactionIsolation;
156
157
158
159
160 private Map<String, Boolean> perUserDefaultReadOnly;
161
162
163
164
165 private transient Map<PoolKey, PooledConnectionManager> managers = createMap();
166
167
168
169
170 public PerUserPoolDataSource() {
171 }
172
173
174
175
176
177
178
179 @SuppressWarnings("resource")
180 public void clear() {
181 managers.values().forEach(manager -> {
182 try {
183 getCPDSConnectionFactoryPool(manager).clear();
184 } catch (final Exception ignored) {
185
186 }
187 });
188 InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
189 }
190
191
192
193
194
195
196 @Override
197 public void close() {
198 managers.values().forEach(manager -> Utils.closeQuietly(getCPDSConnectionFactoryPool(manager)));
199 InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
200 }
201
202
203
204
205 private Map<String, Duration> convertMap(final Map<String, Duration> currentMap, final Map<String, Long> longMap) {
206 final Map<String, Duration> durationMap = createMap();
207 longMap.forEach((k, v) -> durationMap.put(k, toDurationOrNull(v)));
208 if (currentMap == null) {
209 return durationMap;
210 }
211 currentMap.clear();
212 currentMap.putAll(durationMap);
213 return currentMap;
214
215 }
216
217
218
219
220
221
222
223 private <V> V get(final Map<String, V> map, final String userName) {
224 return map != null ? map.get(userName) : null;
225 }
226
227
228
229
230
231
232
233 private <V> V get(final Map<String, V> map, final String userName, final Supplier<V> defaultSupplier) {
234 final V v = get(map, userName);
235 return v != null ? v : defaultSupplier.get();
236 }
237
238 @Override
239 protected PooledConnectionManager getConnectionManager(final UserPassKey upKey) {
240 return managers.get(getPoolKey(upKey.getUserName()));
241 }
242
243
244
245
246
247
248
249 private ObjectPool<PooledConnectionAndInfo> getCPDSConnectionFactoryPool(final PooledConnectionManager manager) {
250 return ((CPDSConnectionFactory) manager).getPool();
251 }
252
253
254
255
256
257
258 public int getNumActive() {
259 return getNumActive(null);
260 }
261
262
263
264
265
266
267
268
269 @SuppressWarnings("resource")
270 public int getNumActive(final String userName) {
271 final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName));
272 return pool == null ? 0 : pool.getNumActive();
273 }
274
275
276
277
278
279
280 public int getNumIdle() {
281 return getNumIdle(null);
282 }
283
284
285
286
287
288
289
290
291 @SuppressWarnings("resource")
292 public int getNumIdle(final String userName) {
293 final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName));
294 return pool == null ? 0 : pool.getNumIdle();
295 }
296
297
298
299
300
301
302
303
304
305 public boolean getPerUserBlockWhenExhausted(final String userName) {
306 return get(perUserBlockWhenExhausted, userName, this::getDefaultBlockWhenExhausted);
307 }
308
309
310
311
312
313
314
315
316 public Boolean getPerUserDefaultAutoCommit(final String userName) {
317 return get(perUserDefaultAutoCommit, userName);
318 }
319
320
321
322
323
324
325
326
327 public Boolean getPerUserDefaultReadOnly(final String userName) {
328 return get(perUserDefaultReadOnly, userName);
329 }
330
331
332
333
334
335
336
337
338
339 public Integer getPerUserDefaultTransactionIsolation(final String userName) {
340 return get(perUserDefaultTransactionIsolation, userName);
341 }
342
343
344
345
346
347
348
349
350
351
352 public Duration getPerUserDurationBetweenEvictionRuns(final String userName) {
353 return get(perUserDurationBetweenEvictionRuns, userName, this::getDefaultDurationBetweenEvictionRuns);
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367 public String getPerUserEvictionPolicyClassName(final String userName) {
368 return get(perUserEvictionPolicyClassName, userName, this::getDefaultEvictionPolicyClassName);
369 }
370
371
372
373
374
375
376
377
378
379 public boolean getPerUserLifo(final String userName) {
380 return get(perUserLifo, userName, this::getDefaultLifo);
381 }
382
383
384
385
386
387
388
389
390
391 public int getPerUserMaxIdle(final String userName) {
392 return get(perUserMaxIdle, userName, this::getDefaultMaxIdle);
393 }
394
395
396
397
398
399
400
401
402
403 public int getPerUserMaxTotal(final String userName) {
404 return get(perUserMaxTotal, userName, this::getDefaultMaxTotal);
405 }
406
407
408
409
410
411
412
413
414
415
416 public Duration getPerUserMaxWaitDuration(final String userName) {
417 return get(perUserMaxWaitDuration, userName, this::getDefaultMaxWait);
418 }
419
420
421
422
423
424
425
426
427
428
429 @Deprecated
430 public long getPerUserMaxWaitMillis(final String userName) {
431 return getPerUserMaxWaitDuration(userName).toMillis();
432 }
433
434
435
436
437
438
439
440
441
442
443 public Duration getPerUserMinEvictableIdleDuration(final String userName) {
444 return get(perUserMinEvictableIdleDuration, userName, this::getDefaultMinEvictableIdleDuration);
445 }
446
447
448
449
450
451
452
453
454
455
456 @Deprecated
457 public long getPerUserMinEvictableIdleTimeMillis(final String userName) {
458 return getPerUserMinEvictableIdleDuration(userName).toMillis();
459 }
460
461
462
463
464
465
466
467
468
469 public int getPerUserMinIdle(final String userName) {
470 return get(perUserMinIdle, userName, this::getDefaultMinIdle);
471 }
472
473
474
475
476
477
478
479
480
481 public int getPerUserNumTestsPerEvictionRun(final String userName) {
482 return get(perUserNumTestsPerEvictionRun, userName, this::getDefaultNumTestsPerEvictionRun);
483 }
484
485
486
487
488
489
490
491
492
493
494 public Duration getPerUserSoftMinEvictableIdleDuration(final String userName) {
495 return get(perUserSoftMinEvictableIdleDuration, userName, this::getDefaultSoftMinEvictableIdleDuration);
496 }
497
498
499
500
501
502
503
504
505
506
507 @Deprecated
508 public long getPerUserSoftMinEvictableIdleTimeMillis(final String userName) {
509 return getPerUserSoftMinEvictableIdleDuration(userName).toMillis();
510 }
511
512
513
514
515
516
517
518
519
520 public boolean getPerUserTestOnBorrow(final String userName) {
521 return get(perUserTestOnBorrow, userName, this::getDefaultTestOnBorrow);
522 }
523
524
525
526
527
528
529
530
531
532 public boolean getPerUserTestOnCreate(final String userName) {
533 return get(perUserTestOnCreate, userName, this::getDefaultTestOnCreate);
534 }
535
536
537
538
539
540
541
542
543
544 public boolean getPerUserTestOnReturn(final String userName) {
545 return get(perUserTestOnReturn, userName, this::getDefaultTestOnReturn);
546 }
547
548
549
550
551
552
553
554
555
556 public boolean getPerUserTestWhileIdle(final String userName) {
557 return get(perUserTestWhileIdle, userName, this::getDefaultTestWhileIdle);
558 }
559
560
561
562
563
564
565
566
567
568
569 @Deprecated
570 public long getPerUserTimeBetweenEvictionRunsMillis(final String userName) {
571 return getPerUserDurationBetweenEvictionRuns(userName).toMillis();
572 }
573
574
575
576
577
578
579
580
581 private ObjectPool<PooledConnectionAndInfo> getPool(final PoolKey poolKey) {
582 final CPDSConnectionFactory mgr = (CPDSConnectionFactory) managers.get(poolKey);
583 return mgr == null ? null : mgr.getPool();
584 }
585
586 @SuppressWarnings("resource")
587 @Override
588 protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String password) throws SQLException {
589 final PoolKey key = getPoolKey(userName);
590 ObjectPool<PooledConnectionAndInfo> pool;
591 PooledConnectionManager manager;
592 synchronized (this) {
593 manager = managers.get(key);
594 if (manager == null) {
595 try {
596 registerPool(userName, password);
597 manager = managers.get(key);
598 } catch (final NamingException e) {
599 throw new SQLException("RegisterPool failed", e);
600 }
601 }
602 pool = getCPDSConnectionFactoryPool(manager);
603 }
604 PooledConnectionAndInfo info = null;
605 try {
606 info = pool.borrowObject();
607 } catch (final NoSuchElementException ex) {
608 throw new SQLException("Could not retrieve connection info from pool", ex);
609 } catch (final Exception e) {
610
611 try {
612 testCPDS(userName, password);
613 } catch (final Exception ex) {
614 throw new SQLException("Could not retrieve connection info from pool", ex);
615 }
616
617 manager.closePool(userName);
618 synchronized (this) {
619 managers.remove(key);
620 }
621 try {
622 registerPool(userName, password);
623 pool = getPool(key);
624 } catch (final NamingException ne) {
625 throw new SQLException("RegisterPool failed", ne);
626 }
627 try {
628 info = pool.borrowObject();
629 } catch (final Exception ex) {
630 throw new SQLException("Could not retrieve connection info from pool", ex);
631 }
632 }
633 return info;
634 }
635
636
637
638
639
640
641
642
643 private PoolKey getPoolKey(final String userName) {
644 return new PoolKey(getDataSourceName(), userName);
645 }
646
647
648
649
650 @Override
651 public Reference getReference() throws NamingException {
652 final Reference ref = new Reference(getClass().getName(), PerUserPoolDataSourceFactory.class.getName(), null);
653 ref.add(new StringRefAddr("instanceKey", getInstanceKey()));
654 return ref;
655 }
656
657 <K, V> Map<K, V> put(Map<K, V> map, final K key, final V value) {
658 if (map == null) {
659 map = createMap();
660 }
661 map.put(key, value);
662 return map;
663 }
664
665
666
667
668
669
670
671
672 @SuppressWarnings("resource")
673 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
674 in.defaultReadObject();
675 this.managers = readObjectImpl().managers;
676 }
677
678 private PerUserPoolDataSource readObjectImpl() throws IOException, ClassNotFoundException {
679 try {
680 return (PerUserPoolDataSource) new PerUserPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null);
681 } catch (final NamingException e) {
682 throw new IOException("NamingException: " + e);
683 }
684 }
685
686 private synchronized void registerPool(final String userName, final String password) throws NamingException, SQLException {
687 final ConnectionPoolDataSource cpds = testCPDS(userName, password);
688
689
690
691 final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, getValidationQuery(), getValidationQueryTimeoutDuration(),
692 isRollbackAfterValidation(), userName, password);
693 factory.setMaxConn(getMaxConnDuration());
694
695 @SuppressWarnings("resource")
696 final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory);
697 factory.setPool(pool);
698 pool.setBlockWhenExhausted(getPerUserBlockWhenExhausted(userName));
699 pool.setEvictionPolicyClassName(getPerUserEvictionPolicyClassName(userName));
700 pool.setLifo(getPerUserLifo(userName));
701 pool.setMaxIdle(getPerUserMaxIdle(userName));
702 pool.setMaxTotal(getPerUserMaxTotal(userName));
703 pool.setMaxWait(getPerUserMaxWaitDuration(userName));
704 pool.setMinEvictableIdleDuration(getPerUserMinEvictableIdleDuration(userName));
705 pool.setMinIdle(getPerUserMinIdle(userName));
706 pool.setNumTestsPerEvictionRun(getPerUserNumTestsPerEvictionRun(userName));
707 pool.setSoftMinEvictableIdleDuration(getPerUserSoftMinEvictableIdleDuration(userName));
708 pool.setTestOnCreate(getPerUserTestOnCreate(userName));
709 pool.setTestOnBorrow(getPerUserTestOnBorrow(userName));
710 pool.setTestOnReturn(getPerUserTestOnReturn(userName));
711 pool.setTestWhileIdle(getPerUserTestWhileIdle(userName));
712 pool.setDurationBetweenEvictionRuns(getPerUserDurationBetweenEvictionRuns(userName));
713 pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log));
714 final PoolKey poolKey = getPoolKey(userName);
715 if (managers.containsKey(poolKey)) {
716 pool.close();
717 throw new IllegalStateException("Pool already contains an entry for this user/password: " + userName);
718 }
719 managers.put(poolKey, factory);
720 }
721
722 private <K, V> Map<K, V> replaceAll(final Map<K, V> currentMap, final Map<K, V> newMap) {
723 if (currentMap == null) {
724 return new HashMap<>(newMap);
725 }
726 currentMap.clear();
727 currentMap.putAll(newMap);
728 return currentMap;
729 }
730
731 void setPerUserBlockWhenExhausted(final Map<String, Boolean> newMap) {
732 assertInitializationAllowed();
733 perUserBlockWhenExhausted = replaceAll(perUserBlockWhenExhausted, newMap);
734 }
735
736
737
738
739
740
741
742
743
744 public void setPerUserBlockWhenExhausted(final String userName, final Boolean value) {
745 assertInitializationAllowed();
746 perUserBlockWhenExhausted = put(perUserBlockWhenExhausted, userName, value);
747 }
748
749 void setPerUserDefaultAutoCommit(final Map<String, Boolean> newMap) {
750 assertInitializationAllowed();
751 perUserDefaultAutoCommit = replaceAll(perUserDefaultAutoCommit, newMap);
752 }
753
754
755
756
757
758
759
760
761
762 public void setPerUserDefaultAutoCommit(final String userName, final Boolean value) {
763 assertInitializationAllowed();
764 perUserDefaultAutoCommit = put(perUserDefaultAutoCommit, userName, value);
765
766 }
767
768 void setPerUserDefaultReadOnly(final Map<String, Boolean> newMap) {
769 assertInitializationAllowed();
770 perUserDefaultReadOnly = replaceAll(perUserDefaultReadOnly, newMap);
771 }
772
773
774
775
776
777
778
779
780
781 public void setPerUserDefaultReadOnly(final String userName, final Boolean value) {
782 assertInitializationAllowed();
783 perUserDefaultReadOnly = put(perUserDefaultReadOnly, userName, value);
784
785 }
786
787 void setPerUserDefaultTransactionIsolation(final Map<String, Integer> newMap) {
788 assertInitializationAllowed();
789 perUserDefaultTransactionIsolation = replaceAll(perUserDefaultTransactionIsolation, newMap);
790 }
791
792
793
794
795
796
797
798
799
800
801 public void setPerUserDefaultTransactionIsolation(final String userName, final Integer value) {
802 assertInitializationAllowed();
803 perUserDefaultTransactionIsolation = put(perUserDefaultTransactionIsolation, userName, value);
804
805 }
806
807 void setPerUserDurationBetweenEvictionRuns(final Map<String, Duration> newMap) {
808 assertInitializationAllowed();
809 perUserDurationBetweenEvictionRuns = replaceAll(perUserDurationBetweenEvictionRuns, newMap);
810 }
811
812
813
814
815
816
817
818
819
820
821
822 public void setPerUserDurationBetweenEvictionRuns(final String userName, final Duration value) {
823 assertInitializationAllowed();
824 perUserDurationBetweenEvictionRuns = put(perUserDurationBetweenEvictionRuns, userName, value);
825
826 }
827
828 void setPerUserEvictionPolicyClassName(final Map<String, String> newMap) {
829 assertInitializationAllowed();
830 perUserEvictionPolicyClassName = replaceAll(perUserEvictionPolicyClassName, newMap);
831 }
832
833
834
835
836
837
838
839
840
841
842
843
844 public void setPerUserEvictionPolicyClassName(final String userName, final String value) {
845 assertInitializationAllowed();
846 perUserEvictionPolicyClassName = put(perUserEvictionPolicyClassName, userName, value);
847 }
848
849 void setPerUserLifo(final Map<String, Boolean> newMap) {
850 assertInitializationAllowed();
851 perUserLifo = replaceAll(perUserLifo, newMap);
852 }
853
854
855
856
857
858
859
860
861
862 public void setPerUserLifo(final String userName, final Boolean value) {
863 assertInitializationAllowed();
864 perUserLifo = put(perUserLifo, userName, value);
865 }
866
867 void setPerUserMaxIdle(final Map<String, Integer> newMap) {
868 assertInitializationAllowed();
869 perUserMaxIdle = replaceAll(perUserMaxIdle, newMap);
870 }
871
872
873
874
875
876
877
878
879
880 public void setPerUserMaxIdle(final String userName, final Integer value) {
881 assertInitializationAllowed();
882 perUserMaxIdle = put(perUserMaxIdle, userName, value);
883 }
884
885 void setPerUserMaxTotal(final Map<String, Integer> newMap) {
886 assertInitializationAllowed();
887 perUserMaxTotal = replaceAll(perUserMaxTotal, newMap);
888 }
889
890
891
892
893
894
895
896
897
898 public void setPerUserMaxTotal(final String userName, final Integer value) {
899 assertInitializationAllowed();
900 perUserMaxTotal = put(perUserMaxTotal, userName, value);
901 }
902
903
904
905
906
907
908
909
910
911
912 public void setPerUserMaxWait(final String userName, final Duration value) {
913 assertInitializationAllowed();
914 perUserMaxWaitDuration = put(perUserMaxWaitDuration, userName, value);
915 }
916
917 void setPerUserMaxWaitDuration(final Map<String, Duration> newMap) {
918 assertInitializationAllowed();
919 perUserMaxWaitDuration = replaceAll(perUserMaxWaitDuration, newMap);
920 }
921
922 void setPerUserMaxWaitMillis(final Map<String, Long> newMap) {
923 assertInitializationAllowed();
924 perUserMaxWaitDuration = convertMap(perUserMaxWaitDuration, newMap);
925 }
926
927
928
929
930
931
932
933
934
935
936 @Deprecated
937 public void setPerUserMaxWaitMillis(final String userName, final Long value) {
938 setPerUserMaxWait(userName, toDurationOrNull(value));
939 }
940
941 void setPerUserMinEvictableIdle(final Map<String, Duration> newMap) {
942 assertInitializationAllowed();
943 perUserMinEvictableIdleDuration = replaceAll(perUserMinEvictableIdleDuration, newMap);
944 }
945
946
947
948
949
950
951
952
953
954
955
956 public void setPerUserMinEvictableIdle(final String userName, final Duration value) {
957 assertInitializationAllowed();
958 perUserMinEvictableIdleDuration = put(perUserMinEvictableIdleDuration, userName, value);
959 }
960
961
962
963
964
965
966
967
968
969
970
971 @Deprecated
972 public void setPerUserMinEvictableIdleTimeMillis(final String userName, final Long value) {
973 setPerUserMinEvictableIdle(userName, toDurationOrNull(value));
974 }
975
976 void setPerUserMinIdle(final Map<String, Integer> newMap) {
977 assertInitializationAllowed();
978 perUserMinIdle = replaceAll(perUserMinIdle, newMap);
979 }
980
981
982
983
984
985
986
987
988
989 public void setPerUserMinIdle(final String userName, final Integer value) {
990 assertInitializationAllowed();
991 perUserMinIdle = put(perUserMinIdle, userName, value);
992 }
993
994 void setPerUserNumTestsPerEvictionRun(final Map<String, Integer> newMap) {
995 assertInitializationAllowed();
996 perUserNumTestsPerEvictionRun = replaceAll(perUserNumTestsPerEvictionRun, newMap);
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 public void setPerUserNumTestsPerEvictionRun(final String userName, final Integer value) {
1009 assertInitializationAllowed();
1010 perUserNumTestsPerEvictionRun = put(perUserNumTestsPerEvictionRun, userName, value);
1011 }
1012
1013 void setPerUserSoftMinEvictableIdle(final Map<String, Duration> newMap) {
1014 assertInitializationAllowed();
1015 perUserSoftMinEvictableIdleDuration = replaceAll(perUserSoftMinEvictableIdleDuration, newMap);
1016 }
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 public void setPerUserSoftMinEvictableIdle(final String userName, final Duration value) {
1029 assertInitializationAllowed();
1030 perUserSoftMinEvictableIdleDuration = put(perUserSoftMinEvictableIdleDuration, userName, value);
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043 @Deprecated
1044 public void setPerUserSoftMinEvictableIdleTimeMillis(final String userName, final Long value) {
1045 setPerUserSoftMinEvictableIdle(userName, toDurationOrNull(value));
1046 }
1047
1048 void setPerUserTestOnBorrow(final Map<String, Boolean> newMap) {
1049 assertInitializationAllowed();
1050 perUserTestOnBorrow = replaceAll(perUserTestOnBorrow, newMap);
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 public void setPerUserTestOnBorrow(final String userName, final Boolean value) {
1062 assertInitializationAllowed();
1063 perUserTestOnBorrow = put(perUserTestOnBorrow, userName, value);
1064 }
1065
1066 void setPerUserTestOnCreate(final Map<String, Boolean> newMap) {
1067 assertInitializationAllowed();
1068 perUserTestOnCreate = replaceAll(perUserTestOnCreate, newMap);
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079 public void setPerUserTestOnCreate(final String userName, final Boolean value) {
1080 assertInitializationAllowed();
1081 perUserTestOnCreate = put(perUserTestOnCreate, userName, value);
1082 }
1083
1084 void setPerUserTestOnReturn(final Map<String, Boolean> newMap) {
1085 assertInitializationAllowed();
1086 perUserTestOnReturn = replaceAll(perUserTestOnReturn, newMap);
1087 }
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 public void setPerUserTestOnReturn(final String userName, final Boolean value) {
1098 assertInitializationAllowed();
1099 perUserTestOnReturn = put(perUserTestOnReturn, userName, value);
1100 }
1101
1102 void setPerUserTestWhileIdle(final Map<String, Boolean> newMap) {
1103 assertInitializationAllowed();
1104 perUserTestWhileIdle = replaceAll(perUserTestWhileIdle, newMap);
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115 public void setPerUserTestWhileIdle(final String userName, final Boolean value) {
1116 assertInitializationAllowed();
1117 perUserTestWhileIdle = put(perUserTestWhileIdle, userName, value);
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 @Deprecated
1131 public void setPerUserTimeBetweenEvictionRunsMillis(final String userName, final Long value) {
1132 setPerUserDurationBetweenEvictionRuns(userName, toDurationOrNull(value));
1133 }
1134
1135 @Override
1136 protected void setupDefaults(final Connection con, final String userName) throws SQLException {
1137 Boolean defaultAutoCommit = isDefaultAutoCommit();
1138 if (userName != null) {
1139 final Boolean userMax = getPerUserDefaultAutoCommit(userName);
1140 if (userMax != null) {
1141 defaultAutoCommit = userMax;
1142 }
1143 }
1144
1145 Boolean defaultReadOnly = isDefaultReadOnly();
1146 if (userName != null) {
1147 final Boolean userMax = getPerUserDefaultReadOnly(userName);
1148 if (userMax != null) {
1149 defaultReadOnly = userMax;
1150 }
1151 }
1152
1153 int defaultTransactionIsolation = getDefaultTransactionIsolation();
1154 if (userName != null) {
1155 final Integer userMax = getPerUserDefaultTransactionIsolation(userName);
1156 if (userMax != null) {
1157 defaultTransactionIsolation = userMax;
1158 }
1159 }
1160
1161 if (defaultAutoCommit != null && con.getAutoCommit() != defaultAutoCommit) {
1162 con.setAutoCommit(defaultAutoCommit);
1163 }
1164
1165 if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
1166 con.setTransactionIsolation(defaultTransactionIsolation);
1167 }
1168
1169 if (defaultReadOnly != null && con.isReadOnly() != defaultReadOnly) {
1170 con.setReadOnly(defaultReadOnly);
1171 }
1172 }
1173
1174 private Duration toDurationOrNull(final Long millis) {
1175 return millis == null ? null : Duration.ofMillis(millis);
1176 }
1177 }