View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.appender.db.jdbc;
19  
20  import java.util.Arrays;
21  import java.util.Collection;
22  import java.util.List;
23  
24  import org.apache.commons.dbcp2.PoolableConnectionFactory;
25  import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
26  import org.apache.logging.log4j.core.Core;
27  import org.apache.logging.log4j.core.config.plugins.Plugin;
28  import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
29  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
30  import org.apache.logging.log4j.core.config.plugins.PluginElement;
31  import org.apache.logging.log4j.status.StatusLogger;
32  import org.apache.logging.log4j.util.Strings;
33  
34  /**
35   * Configures an Apache Commons DBCP {@link PoolableConnectionFactory}.
36   *
37   * @since 2.11.2
38   */
39  @Plugin(name = "PoolableConnectionFactory", category = Core.CATEGORY_NAME, printObject = true)
40  public class PoolableConnectionFactoryConfig {
41  
42      public static class Builder implements org.apache.logging.log4j.core.util.Builder<PoolableConnectionFactoryConfig> {
43  
44          private static final PoolableConnectionFactory DEFAULT = new PoolableConnectionFactory(null, null);
45  
46          /**
47           * Internal constant to indicate the level is not set.
48           */
49          private static final int UNKNOWN_TRANSACTION_ISOLATION = -1;
50  
51          // All of these instance variables match DBCP WRT Boolean vs. boolean.
52          // All of these defaults are the same as in PoolableConnectionFactory.
53  
54          @PluginBuilderAttribute
55          private boolean cacheState;
56  
57          // TODO
58          @PluginElement("ConnectionInitSqls")
59          private String[] connectionInitSqls;
60  
61          @PluginBuilderAttribute
62          private Boolean defaultAutoCommit;
63  
64          @PluginBuilderAttribute
65          private String defaultCatalog;
66  
67          @PluginBuilderAttribute
68          private Integer defaultQueryTimeoutSeconds = DEFAULT.getDefaultQueryTimeout();
69  
70          @PluginBuilderAttribute
71          private Boolean defaultReadOnly;
72  
73          @PluginBuilderAttribute
74          private int defaultTransactionIsolation = UNKNOWN_TRANSACTION_ISOLATION;
75  
76          // TODO
77          @PluginElement("DisconnectionSqlCodes")
78          private String[] disconnectionSqlCodes = (String[]) (DEFAULT.getDisconnectionSqlCodes() == null ? null
79                  : DEFAULT.getDisconnectionSqlCodes().toArray());
80  
81          @PluginBuilderAttribute
82          private boolean autoCommitOnReturn = DEFAULT.isEnableAutoCommitOnReturn();
83  
84          @PluginBuilderAttribute
85          private boolean fastFailValidation = DEFAULT.isFastFailValidation();
86  
87          @PluginBuilderAttribute
88          private long maxConnLifetimeMillis = -1;
89  
90          @PluginBuilderAttribute
91          private int maxOpenPreparedStatements = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL_PER_KEY;
92  
93          @PluginBuilderAttribute
94          private boolean poolStatements;
95  
96          @PluginBuilderAttribute
97          private boolean rollbackOnReturn = DEFAULT.isRollbackOnReturn();
98  
99          @PluginBuilderAttribute
100         private String validationQuery;
101 
102         @PluginBuilderAttribute
103         private int validationQueryTimeoutSeconds = -1;
104 
105         private List<String> asList(final String[] array) {
106             return array == null ? null : Arrays.asList(array);
107         }
108 
109         @Override
110         public PoolableConnectionFactoryConfig build() {
111             return new PoolableConnectionFactoryConfig(cacheState, asList(connectionInitSqls), defaultAutoCommit,
112                     defaultCatalog, defaultQueryTimeoutSeconds, defaultReadOnly, defaultTransactionIsolation,
113                     asList(disconnectionSqlCodes), autoCommitOnReturn, fastFailValidation, maxConnLifetimeMillis,
114                     maxOpenPreparedStatements, poolStatements, rollbackOnReturn, validationQuery,
115                     validationQueryTimeoutSeconds);
116         }
117 
118         public Builder setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
119             this.autoCommitOnReturn = autoCommitOnReturn;
120             return this;
121         }
122 
123         public Builder setCacheState(final boolean cacheState) {
124             this.cacheState = cacheState;
125             return this;
126         }
127 
128         public Builder setConnectionInitSqls(final String... connectionInitSqls) {
129             this.connectionInitSqls = connectionInitSqls;
130             return this;
131         }
132 
133         public Builder setDefaultAutoCommit(final Boolean defaultAutoCommit) {
134             this.defaultAutoCommit = defaultAutoCommit;
135             return this;
136         }
137 
138         public Builder setDefaultCatalog(final String defaultCatalog) {
139             this.defaultCatalog = defaultCatalog;
140             return this;
141         }
142 
143         public Builder setDefaultQueryTimeoutSeconds(final Integer defaultQueryTimeoutSeconds) {
144             this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
145             return this;
146         }
147 
148         public Builder setDefaultReadOnly(final Boolean defaultReadOnly) {
149             this.defaultReadOnly = defaultReadOnly;
150             return this;
151         }
152 
153         public Builder setDefaultTransactionIsolation(final int defaultTransactionIsolation) {
154             this.defaultTransactionIsolation = defaultTransactionIsolation;
155             return this;
156         }
157 
158         public Builder setDisconnectionSqlCodes(final String... disconnectionSqlCodes) {
159             this.disconnectionSqlCodes = disconnectionSqlCodes;
160             return this;
161         }
162 
163         public Builder setFastFailValidation(final boolean fastFailValidation) {
164             this.fastFailValidation = fastFailValidation;
165             return this;
166         }
167 
168         public Builder setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
169             this.maxConnLifetimeMillis = maxConnLifetimeMillis;
170             return this;
171         }
172 
173         public Builder setMaxOpenPreparedStatements(final int maxOpenPreparedStatements) {
174             this.maxOpenPreparedStatements = maxOpenPreparedStatements;
175             return this;
176         }
177 
178         public Builder setPoolStatements(final boolean poolStatements) {
179             this.poolStatements = poolStatements;
180             return this;
181         }
182 
183         public Builder setRollbackOnReturn(final boolean rollbackOnReturn) {
184             this.rollbackOnReturn = rollbackOnReturn;
185             return this;
186         }
187 
188         public Builder setValidationQuery(final String validationQuery) {
189             this.validationQuery = validationQuery;
190             return this;
191         }
192 
193         public Builder setValidationQueryTimeoutSeconds(final int validationQueryTimeoutSeconds) {
194             this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
195             return this;
196         }
197     }
198 
199     // ALL of these instance variables match DBCP WRT Boolean vs. boolean.
200 
201     @PluginBuilderFactory
202     public static Builder newBuilder() {
203         return new Builder();
204     }
205 
206     private final boolean cacheState;
207     private final Collection<String> connectionInitSqls;
208     private final Boolean defaultAutoCommit;
209     private final String defaultCatalog;
210     private final Integer defaultQueryTimeoutSeconds;
211     private final Boolean defaultReadOnly;
212     private final int defaultTransactionIsolation;
213     private final Collection<String> disconnectionSqlCodes;
214     private final boolean autoCommitOnReturn;
215     private final boolean fastFailValidation;
216     private final long maxConnLifetimeMillis;
217     private final int maxOpenPreparedStatements;
218     private final boolean poolStatements;
219     private final boolean rollbackOnReturn;
220     private final String validationQuery;
221 
222     private final int validationQueryTimeoutSeconds;
223 
224     private PoolableConnectionFactoryConfig(final boolean cacheState, final Collection<String> connectionInitSqls,
225             final Boolean defaultAutoCommit, final String defaultCatalog, final Integer defaultQueryTimeoutSeconds,
226             final Boolean defaultReadOnly, final int defaultTransactionIsolation,
227             final Collection<String> disconnectionSqlCodes, final boolean enableAutoCommitOnReturn,
228             final boolean fastFailValidation, final long maxConnLifetimeMillis, final int maxOpenPreparedStatements,
229             final boolean poolStatements, final boolean rollbackOnReturn, final String validationQuery,
230             final int validationQueryTimeoutSeconds) {
231         super();
232         this.cacheState = cacheState;
233         this.connectionInitSqls = connectionInitSqls;
234         this.defaultAutoCommit = defaultAutoCommit;
235         this.defaultCatalog = Strings.trimToNull(defaultCatalog);
236         this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
237         this.defaultReadOnly = defaultReadOnly;
238         this.defaultTransactionIsolation = defaultTransactionIsolation;
239         this.disconnectionSqlCodes = disconnectionSqlCodes;
240         this.autoCommitOnReturn = enableAutoCommitOnReturn;
241         this.fastFailValidation = fastFailValidation;
242         this.maxConnLifetimeMillis = maxConnLifetimeMillis;
243         this.maxOpenPreparedStatements = maxOpenPreparedStatements;
244         this.poolStatements = poolStatements;
245         this.rollbackOnReturn = rollbackOnReturn;
246         this.validationQuery = Strings.trimToNull(validationQuery);
247         this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
248     }
249 
250     public void init(final PoolableConnectionFactory poolableConnectionFactory) {
251         if (poolableConnectionFactory != null) {
252             StatusLogger.getLogger().debug("Initializing PoolableConnectionFactory {} with {}",
253                     poolableConnectionFactory, this);
254             poolableConnectionFactory.setCacheState(cacheState);
255             poolableConnectionFactory.setConnectionInitSql(connectionInitSqls);
256             poolableConnectionFactory.setDefaultAutoCommit(defaultAutoCommit);
257             poolableConnectionFactory.setDefaultCatalog(defaultCatalog);
258             poolableConnectionFactory.setDefaultQueryTimeout(defaultQueryTimeoutSeconds);
259             poolableConnectionFactory.setDefaultReadOnly(defaultReadOnly);
260             poolableConnectionFactory.setDefaultTransactionIsolation(defaultTransactionIsolation);
261             poolableConnectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes);
262             poolableConnectionFactory.setEnableAutoCommitOnReturn(autoCommitOnReturn);
263             poolableConnectionFactory.setFastFailValidation(fastFailValidation);
264             poolableConnectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
265             poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
266             poolableConnectionFactory.setPoolStatements(poolStatements);
267             poolableConnectionFactory.setRollbackOnReturn(rollbackOnReturn);
268             poolableConnectionFactory.setValidationQuery(validationQuery);
269             poolableConnectionFactory.setValidationQueryTimeout(validationQueryTimeoutSeconds);
270         }
271 
272     }
273 
274     @Override
275     public String toString() {
276         return String.format(
277                 "PoolableConnectionFactoryConfig [cacheState=%s, connectionInitSqls=%s, defaultAutoCommit=%s, defaultCatalog=%s, defaultQueryTimeoutSeconds=%s, defaultReadOnly=%s, defaultTransactionIsolation=%s, disconnectionSqlCodes=%s, enableAutoCommitOnReturn=%s, fastFailValidation=%s, maxConnLifetimeMillis=%s, maxOpenPreparedStatements=%s, poolStatements=%s, rollbackOnReturn=%s, validationQuery=%s, validationQueryTimeoutSeconds=%s]",
278                 cacheState, connectionInitSqls, defaultAutoCommit, defaultCatalog, defaultQueryTimeoutSeconds,
279                 defaultReadOnly, defaultTransactionIsolation, disconnectionSqlCodes, autoCommitOnReturn,
280                 fastFailValidation, maxConnLifetimeMillis, maxOpenPreparedStatements, poolStatements, rollbackOnReturn,
281                 validationQuery, validationQueryTimeoutSeconds);
282     }
283 
284 }