1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package edu.internet2.middleware.subject.provider;
21
22 import java.sql.Connection;
23 import java.sql.SQLException;
24 import java.util.Properties;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import com.mchange.v2.c3p0.ComboPooledDataSource;
31 import com.mchange.v2.c3p0.DataSources;
32
33 import edu.internet2.middleware.subject.SourceUnavailableException;
34 import edu.internet2.middleware.subject.SubjectUtils;
35
36
37
38
39
40 public class C3p0JdbcConnectionProvider implements JdbcConnectionProvider {
41
42
43 private boolean connectionReadOnly;
44
45
46 private ComboPooledDataSource comboPooledDataSource;
47
48
49 private static Log log = LogFactory.getLog(C3p0JdbcConnectionProvider.class);
50
51
52
53
54 public JdbcConnectionBean connectionBean() throws SQLException {
55 Connection connection = this.comboPooledDataSource.getConnection();
56 connection.setReadOnly(this.connectionReadOnly);
57 return new C3p0JdbcConnectionBean(connection);
58 }
59
60
61
62
63 public static class C3p0JdbcConnectionBean implements JdbcConnectionBean {
64
65
66 private Connection connection;
67
68
69
70
71
72 public C3p0JdbcConnectionBean(Connection theConnection) {
73 this.connection = theConnection;
74 }
75
76
77
78 public Connection connection() throws SQLException {
79 return this.connection;
80 }
81
82
83
84 public void doneWithConnection() {
85 }
86
87
88
89 public void doneWithConnectionError(Throwable t) {
90 throw new RuntimeException(t);
91 }
92
93
94
95
96 public void doneWithConnectionFinally() {
97 if (this.connection != null) {
98 try {
99
100 this.connection.close();
101 } catch (SQLException ex) {
102 log.info("Error while closing JDBC Connection.", ex);
103 }
104 }
105 }
106
107 }
108
109
110
111
112
113 @Override
114 protected void finalize() throws Throwable {
115 super.finalize();
116 DataSources.destroy( this.comboPooledDataSource );
117 }
118
119
120
121
122 public void init(Properties properties, String sourceId, String driver, Integer maxActive, int defaultMaxActive,
123 Integer maxIdle, int defaultMaxIdle, Integer maxWaitSeconds,
124 int defaultMaxWaitSeconds, String dbUrl, String dbUser, String dbPassword,
125 Boolean readOnly, boolean readOnlyDefault, String jdbcConfigId) throws SourceUnavailableException {
126
127 if (!StringUtils.isBlank(jdbcConfigId)) {
128 throw new RuntimeException("Cannot pass in jdbcConfigId for C3p0JdbcConnectionProvider, its only valid for GrouperJdbcConnectionProvider!");
129 }
130
131 this.comboPooledDataSource = new ComboPooledDataSource();
132
133 JDBCSourceAdapter.loadDriver(sourceId, driver);
134
135
136
137
138
139
140
141 this.comboPooledDataSource.setJdbcUrl( dbUrl );
142 this.comboPooledDataSource.setUser(dbUser);
143 this.comboPooledDataSource.setPassword(dbPassword);
144 this.comboPooledDataSource.setMaxPoolSize(SubjectUtils.defaultIfNull(maxActive, defaultMaxActive));
145
146
147 if (maxIdle != null) {
148 log.warn("maxIdle is not available for c3p0 (in subject API: " + sourceId + ")");
149 }
150 int checkoutTimeout = 1000*SubjectUtils.defaultIfNull(maxWaitSeconds, defaultMaxWaitSeconds);
151
152 checkoutTimeout = checkoutTimeout < 0 ? (5 * 60 * 1000) : checkoutTimeout;
153 this.comboPooledDataSource.setCheckoutTimeout(checkoutTimeout);
154 this.connectionReadOnly = SubjectUtils.defaultIfNull(readOnly, readOnlyDefault);
155
156 {
157
158 String maxConnectionAgeString = properties.getProperty("maxConnectionAge");
159
160 if (!StringUtils.isBlank(maxConnectionAgeString)) {
161 int maxConnectionAgeInteger = SubjectUtils.intValue(maxConnectionAgeString);
162 this.comboPooledDataSource.setMaxConnectionAge(maxConnectionAgeInteger);
163 }
164 }
165
166 {
167
168 String testConnectionOnCheckoutString = properties.getProperty("testConnectionOnCheckout");
169
170 if (!StringUtils.isBlank(testConnectionOnCheckoutString)) {
171 boolean testConnectionOnCheckout = SubjectUtils.booleanValue(testConnectionOnCheckoutString);
172 this.comboPooledDataSource.setTestConnectionOnCheckout(testConnectionOnCheckout);
173 }
174
175 }
176
177 {
178
179 String preferredTestQuery = properties.getProperty("preferredTestQuery");
180
181 if (!StringUtils.isBlank(preferredTestQuery)) {
182 this.comboPooledDataSource.setPreferredTestQuery(preferredTestQuery);
183 }
184
185 }
186
187
188 {
189
190 String idleConnectionTestPeriodString = properties.getProperty("idleConnectionTestPeriod");
191
192 if (!StringUtils.isBlank(idleConnectionTestPeriodString)) {
193 int idleConnectionTestPeriodInteger = SubjectUtils.intValue(idleConnectionTestPeriodString);
194 this.comboPooledDataSource.setIdleConnectionTestPeriod(idleConnectionTestPeriodInteger);
195 }
196
197 }
198
199
200 }
201
202
203
204
205 public boolean requiresJdbcConfigInSourcesXml() {
206 return true;
207 }
208
209 }